Serious-Engine/Sources/SeriousSkaStudio/SplitterFrame.cpp
2016-03-11 18:20:51 -06:00

328 lines
9.0 KiB
C++

/* 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;ipar<ctParentLevels;ipar++) {
pFloatingParent = pFloatingParent->GetParent();
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);
}