2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
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.
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.
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/>.
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.
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.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
36 //IMPLEMENT_DYNAMIC ( CTabsDlg , CDialog )
37 CTabsDlg::CTabsDlg(UINT ID , CWnd* pParent /*=NULL*/)
38 : CDialog(ID, pParent)
40 m_DragTabActive = false;
43 BEGIN_MESSAGE_MAP(CTabsDlg, CDialog)
45 // ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTab1)
52 void CTabsDlg::DoDataExchange(CDataExchange* pDX)
54 CDialog::DoDataExchange(pDX);
55 DDX_Control(pDX, IDC_TAB_INSPECTOR, m_Tabs);
58 // CTabsDlg message handlers
60 BOOL CTabsDlg::OnInitDialog()
62 CDialog::OnInitDialog();
64 return TRUE; // return TRUE unless you set the focus to a control
67 void CTabsDlg::OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult)
69 int ID = TabCtrl_GetCurSel ( pNMHDR->hwndFrom );
74 item.mask = TCIF_PARAM;
76 ShowAllWindows ( FALSE );
77 TabCtrl_GetItem (m_Tabs.GetSafeHwnd() , ID , &item);
79 DockedWindowInfo* info = (DockedWindowInfo*)item.lParam;
82 info->m_TabControlIndex = ID;
83 info->m_Window->ShowWindow(TRUE);
87 void CTabsDlg::DockWindow ( int ID , bool dock )
89 DockedWindowInfo* info = NULL;
90 m_Windows.Lookup ( (WORD)ID , (void*&)info );
93 ASSERT ( m_Tabs.GetSafeHwnd() );
95 ShowAllWindows ( FALSE );
99 //make a containing window and assign the dialog to it
101 CString classname = AfxRegisterWndClass ( CS_DBLCLKS , 0 , 0 , 0 );
102 info->m_State = DockedWindowInfo::FLOATING;
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);
109 info->m_Container.SetDockManager(this);
110 info->m_Container.ShowWindow(TRUE);
111 info->m_Container.SetDialog ( info->m_Window , info->m_ID );
113 if (info->m_TabControlIndex >= 0 )
115 m_Tabs.DeleteItem( info->m_TabControlIndex );
118 if ( m_Tabs.GetItemCount() > 0 )
120 m_Tabs.SetCurFocus( 0 );
123 CString placementName = info->m_Title + "Placement";
124 LoadWindowPlacement(info->m_Container , placementName);
128 info->m_State = DockedWindowInfo::DOCKED;
130 info->m_TabControlIndex = m_Tabs.InsertItem( TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM , 0 , info->m_Title , info->m_ImageID , (LPARAM)info);
132 info->m_Window->SetParent ( this );
133 info->m_Window->ShowWindow (TRUE);
135 info->m_Container.SetDockManager( NULL ); //so it doesn't try to call back and redock this window
136 info->m_Container.DestroyWindow ();
139 GetWindowRect ( rect );
141 //stupid hack to get the window reitself properly
142 rect.DeflateRect(0,0,0,1);
144 rect.InflateRect(0,0,0,1);
148 UpdateTabControlIndices ();
151 if ( info->m_DockCallback )
153 info->m_DockCallback ( dock , info->m_ID , info->m_Window );
155 SaveWindowPlacement ();
158 int CTabsDlg::PreTranslateMessage ( MSG* msg )
160 if ( msg->message == WM_LBUTTONDBLCLK && msg->hwnd == m_Tabs.GetSafeHwnd() )
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;
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;
176 return CDialog::PreTranslateMessage(msg);
179 bool CTabsDlg::RectWithinDockManager ( CRect& rect )
181 CRect tabsRect,intersectionRect;
183 m_Tabs.GetWindowRect ( tabsRect );
184 intersectionRect.IntersectRect( tabsRect , rect );
186 return !(intersectionRect.IsRectEmpty());
189 void CTabsDlg::OnLButtonDown(UINT nFlags, CPoint point)
191 CDialog::OnLButtonDown(nFlags, point);
194 void CTabsDlg::OnLButtonUp(UINT nFlags, CPoint point)
196 if ( m_DragTabActive && ((abs ( point.x - m_DragDownPoint.x ) > 50) || (abs ( point.y - m_DragDownPoint.y ) > 50)))
199 m_DragTabActive = false;
201 CDialog::OnLButtonUp(nFlags, point);
205 void CTabsDlg::HandleUndock ()
208 item.mask = TCIF_PARAM;
210 int curSel = TabCtrl_GetCurSel ( m_Tabs.GetSafeHwnd());
212 TabCtrl_GetItem (m_Tabs.GetSafeHwnd() , curSel , &item);
214 DockedWindowInfo* info = (DockedWindowInfo*)item.lParam;
217 DockWindow ( info->m_ID , false );
220 void CTabsDlg::OnMouseMove(UINT nFlags, CPoint point)
222 CDialog::OnMouseMove(nFlags, point);
226 void CTabsDlg::AddDockedWindow ( CWnd* wnd , int ID , int imageID , const CString& title , bool dock , pfnOnDockEvent dockCallback )
228 DockedWindowInfo* info = NULL;
229 m_Windows.Lookup( (WORD)ID , (void*&)info);
232 ASSERT ( info == NULL );
234 info = new DockedWindowInfo ( wnd , ID , imageID , title , dockCallback);
236 m_Windows.SetAt ( (WORD)ID , info );
237 DockWindow ( ID , dock );
239 UpdateTabControlIndices ();
242 void CTabsDlg::ShowAllWindows ( bool show )
246 DockedWindowInfo* info = NULL;
247 for( pos = m_Windows.GetStartPosition(); pos != NULL ; )
249 m_Windows.GetNextAssoc( pos, ID, (void*&)info );
250 ASSERT ( info->m_Window );
251 if ( info->m_State == DockedWindowInfo::DOCKED )
253 info->m_Window->ShowWindow( show );
258 void CTabsDlg::FocusWindow ( int ID )
260 DockedWindowInfo* info = NULL;
261 m_Windows.Lookup( (WORD)ID , (void*&)info);
264 ASSERT ( info->m_Window );
266 if ( info->m_State == DockedWindowInfo::DOCKED )
268 TabCtrl_SetCurFocus ( m_Tabs.GetSafeHwnd() , info->m_TabControlIndex );
272 info->m_Container.SetFocus();
276 void CTabsDlg::UpdateTabControlIndices ()
279 item.mask = TCIF_PARAM;
281 DockedWindowInfo* info = NULL;
282 int itemCount = m_Tabs.GetItemCount();
284 for ( int i = 0 ; i < itemCount ; i ++ )
286 if ( !m_Tabs.GetItem( i , &item ) )
288 Sys_Error ( "UpdateTabControlIndices(): GetItem failed!\n" );
290 info = (DockedWindowInfo*)item.lParam;
292 info->m_TabControlIndex = i;
295 void CTabsDlg::OnDestroy()
298 item.mask = TCIF_PARAM;
300 DockedWindowInfo* info = NULL;
302 for ( int i = 0 ; i < m_Tabs.GetItemCount() ; i ++ )
304 m_Tabs.GetItem( i , &item );
305 info = (DockedWindowInfo*)item.lParam;
310 CDialog::OnDestroy();
314 bool CTabsDlg::IsDocked ( CWnd* wnd )
317 DockedWindowInfo* info = NULL;
319 CString placementName;
323 for( pos = m_Windows.GetStartPosition(); pos != NULL ; )
325 m_Windows.GetNextAssoc( pos, wID, (void*&)info );
327 if ( info->m_Window == wnd ) {
328 docked = (info->m_State == DockedWindowInfo::DOCKED);
335 void CTabsDlg::SaveWindowPlacement( int ID )
337 DockedWindowInfo* info = NULL;
339 CString placementName;
343 for( pos = m_Windows.GetStartPosition(); pos != NULL ; )
345 m_Windows.GetNextAssoc( pos, wID, (void*&)info );
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);