/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // SplitterFrame.cpp : implementation file // #include "stdafx.h" #include "seriousskastudio.h" #include "SplitterFrame.h" #include "MainFrm.h" #include "DlgTemplate.h" #ifdef _DEBUG #undef new #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CSplitterFrame IMPLEMENT_DYNCREATE(CSplitterFrame, CWnd) #define SET_BAR_SIZE( bar, dx, dy) \ bar.m_Size.cx = dx; \ bar.m_Size.cy = dy; //bar.CalcDynamicLayout(0, LM_HORZDOCK) CSplitterFrame::CSplitterFrame() { pchCursor = IDC_NO; iSplitterSize = 6; } CSplitterFrame::~CSplitterFrame() { } BEGIN_MESSAGE_MAP(CSplitterFrame, CWnd) //{{AFX_MSG_MAP(CSplitterFrame) ON_WM_SETCURSOR() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_SIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSplitterFrame message handlers // Resize splitter void CSplitterFrame::SetSize(INDEX iWidth,INDEX iHeight) { SetWindowPos(&wndTop,0,0,iWidth,iHeight,SWP_NOMOVE); } // Set new position for splitter void CSplitterFrame::SetAbsPosition(CPoint pt) { CWnd *pParent = GetParent(); ASSERT(pParent!=NULL); pParent->ScreenToClient(&pt); SetWindowPos(&wndTop,pt.x,pt.y,0,0,SWP_NOSIZE); } // Get position of splitter CPoint CSplitterFrame::GetAbsPosition() { CRect rc; GetWindowRect(&rc); return CPoint(rc.left,rc.top); } // Change parent of splitter void CSplitterFrame::ChangeParent(CWnd *pNewParent) { CPoint &ptCurrent = GetAbsPosition(); SetParent(pNewParent); SetAbsPosition(ptCurrent); } void CSplitterFrame::EnableDocking() { sp_bDockingEnabled = TRUE; } void CSplitterFrame::SetDockingSide(UINT uiDockSide) { CWnd *pParent = GetParent(); CRect rcParent; pParent->GetWindowRect(&rcParent); sp_uiDockSide = uiDockSide; // is splitter attached on left side if(uiDockSide == AFX_IDW_DOCKBAR_LEFT) { SetSize(iSplitterSize,rcParent.bottom - rcParent.top); SetAbsPosition(CPoint(rcParent.left,rcParent.top)); pchCursor = IDC_SIZEWE; ShowWindow(SW_SHOW); // is splitter attached on right side } else if(uiDockSide == AFX_IDW_DOCKBAR_RIGHT) { SetSize(iSplitterSize,rcParent.bottom - rcParent.top); SetAbsPosition(CPoint(rcParent.right - iSplitterSize,rcParent.top)); pchCursor = IDC_SIZEWE; ShowWindow(SW_SHOW); // is splitter attached on top side } else if(uiDockSide == AFX_IDW_DOCKBAR_TOP) { SetSize(rcParent.right - rcParent.left,iSplitterSize); SetAbsPosition(CPoint(rcParent.left,rcParent.top)); pchCursor = IDC_SIZENS; ShowWindow(SW_SHOW); // is splitter attached on bottom side } else if(uiDockSide == AFX_IDW_DOCKBAR_BOTTOM) { SetSize(rcParent.right - rcParent.left,iSplitterSize); SetAbsPosition(CPoint(rcParent.left,rcParent.bottom-iSplitterSize)); pchCursor = IDC_SIZENS; ShowWindow(SW_SHOW); // is splitter floating } else if(uiDockSide == AFX_IDW_DOCKBAR_FLOAT) { ShowWindow(SW_HIDE); } else { ASSERT(FALSE); } } // Resize parent void CSplitterFrame::UpdateParent() { CRect rcParent; CRect rcMainFrame; CRect rcMainClientFrame; CPoint pt = GetAbsPosition(); CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); CDlgTemplate &wndParent = *(CDlgTemplate*)GetParent(); pMainFrame->GetClientRect(&rcMainClientFrame); pMainFrame->GetWindowRect(&rcMainFrame); pt.x -=rcMainFrame.left; pt.y -=rcMainFrame.top; wndParent.GetWindowRect(&rcParent); wndParent.ShowWindow(SW_HIDE); INDEX iWidth = rcParent.right - rcParent.left; INDEX iHeight = rcParent.bottom - rcParent.top; if(sp_bDockingEnabled) { pMainFrame->FloatControlBar(&wndParent,CPoint(rcParent.left,rcParent.top)); // is splitter attached on left side if(sp_uiDockSide == AFX_IDW_DOCKBAR_LEFT) { SET_BAR_SIZE(wndParent,rcMainClientFrame.right - pt.x,iHeight); // is splitter attached on right side } else if(sp_uiDockSide == AFX_IDW_DOCKBAR_RIGHT) { SET_BAR_SIZE(wndParent,pt.x,iHeight); // is splitter attached on top side } else if(sp_uiDockSide == AFX_IDW_DOCKBAR_TOP) { SET_BAR_SIZE(wndParent,iWidth,iHeight + sp_ptStartPoint.y - pt.y); // is splitter attached on bottom side } else if(sp_uiDockSide == AFX_IDW_DOCKBAR_BOTTOM) { ASSERT(FALSE); } // Chose docking side INDEX iDockSide = 0; // is splitter attached on left side if(sp_uiDockSide==AFX_IDW_DOCKBAR_LEFT) { iDockSide = AFX_IDW_DOCKBAR_RIGHT; // is splitter attached on right side } else if(sp_uiDockSide==AFX_IDW_DOCKBAR_RIGHT) { iDockSide = AFX_IDW_DOCKBAR_LEFT; // is splitter attached on top side } else if(sp_uiDockSide==AFX_IDW_DOCKBAR_TOP) { iDockSide = AFX_IDW_DOCKBAR_BOTTOM; // is splitter attached on bottom side } else if(sp_uiDockSide==AFX_IDW_DOCKBAR_BOTTOM) { iDockSide = AFX_IDW_DOCKBAR_TOP; } pMainFrame->DockControlBar(&wndParent,iDockSide); } else { SET_BAR_SIZE(wndParent,300,300); // wndParent.SetWindowPos(&wndBottom,0,0,100,300,SWP_NOZORDER); //pMainFrame->FloatControlBar(&wndParent,CPoint(rcParent.left,rcParent.top)); //pMainFrame->DockControlBar(&wndParent,AFX_IDW_DOCKBAR_BOTTOM); } wndParent.ShowWindow(SW_SHOW); wndParent.UpdateWindow(); } // on left mouse button down void CSplitterFrame::OnLButtonDown(UINT nFlags, CPoint point) { INDEX ctParentLevels = 0; if(sp_bDockingEnabled) { ctParentLevels = 1; } CRect rc; ASSERT(GetParent()!=NULL); pDockedParent = GetParent(); pFloatingParent = pDockedParent->GetParent(); ASSERT(pFloatingParent!=NULL); for(INDEX ipar=0;iparGetParent(); ASSERT(pFloatingParent!=NULL); } /* CPoint pt = GetAbsPosition(); pt.x += point.x; SetAbsPosition(pt); */ SetCapture(); sp_ptStartPoint = GetAbsPosition(); ChangeParent(pFloatingParent); CWnd::OnLButtonDown(nFlags, point); } // on left mouse button up void CSplitterFrame::OnLButtonUp(UINT nFlags, CPoint point) { if(GetCapture()==this) { ReleaseCapture(); ChangeParent(pDockedParent); UpdateParent(); // SetOrientation(uiOrientation); } CWnd::OnLButtonUp(nFlags, point); } // on mouse move void CSplitterFrame::OnMouseMove(UINT nFlags, CPoint point) { if(GetCapture()==this) { CPoint ptCursor; GetCursorPos(&ptCursor); CPoint pt = GetAbsPosition(); if(sp_uiDockSide==AFX_IDW_DOCKBAR_LEFT || sp_uiDockSide==AFX_IDW_DOCKBAR_RIGHT) { pt.x = ptCursor.x; } else if(sp_uiDockSide==AFX_IDW_DOCKBAR_TOP || sp_uiDockSide==AFX_IDW_DOCKBAR_BOTTOM) { pt.y = ptCursor.y; } SetAbsPosition(pt); } CWnd::OnMouseMove(nFlags, point); } /* void CSplitterFrame::OnLButtonUp(UINT nFlags, CPoint point) { if(!theApp.m_dlgBarTreeView.IsFloating()) { SetParent(&theApp.m_dlgBarTreeView); ReleaseCapture(); CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); // move dlgbar CRect rc; CRect rcMain; pMainFrame->GetWindowRect(rcMain); theApp.m_dlgBarTreeView.GetWindowRect(&rc); CPoint pt = CPoint(rc.left,rc.top); theApp.m_dlgBarTreeView.ShowWindow(SW_HIDE); // undock INDEX iDockSide = theApp.m_dlgBarTreeView.GetDockingSide(); pMainFrame->FloatControlBar(&theApp.m_dlgBarTreeView,pt); // resize if(iDockSide == AFX_IDW_DOCKBAR_LEFT) { INDEX iPosXadd = 2+rcMain.right-rcMain.left; INDEX iPosX = GetPosX(); if(iPosX<10) iPosX=10; else if(iPosX>iPosXadd-10) iPosX=iPosXadd-10; SET_BAR_SIZE(theApp.m_dlgBarTreeView,iPosX,rc.bottom-rc.top); } else if(iDockSide == AFX_IDW_DOCKBAR_RIGHT) { INDEX iPosXadd = 2+rcMain.right-rcMain.left; INDEX iPosX = GetPosX(); if(iPosX>iPosXadd-10) iPosX=iPosXadd-10; else if(iPosX<10) iPosX=10; SET_BAR_SIZE(theApp.m_dlgBarTreeView,iPosXadd-iPosX,rc.bottom-rc.top); } pMainFrame->DockControlBar(&theApp.m_dlgBarTreeView,iDockSide); theApp.m_dlgBarTreeView.ShowWindow(SW_SHOW); } CWnd::OnLButtonUp(nFlags, point); } */ BOOL CSplitterFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { ::SetCursor(AfxGetApp()->LoadStandardCursor(pchCursor)); return TRUE; return CWnd::OnSetCursor(pWnd, nHitTest, message); } void CSplitterFrame::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); }