You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1649 lines
41 KiB
C++
1649 lines
41 KiB
C++
// XTPDockingPaneManager.cpp : implementation of the CXTPDockingPaneManager class.
|
|
//
|
|
// This file is a part of the XTREME DOCKINGPANE MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPImageManager.h"
|
|
#include "Common/XTPToolTipContext.h"
|
|
#include "Common/XTPPropExchange.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
|
|
#include "TabManager/XTPTabManager.h"
|
|
|
|
#include "XTPDockingPaneDefines.h"
|
|
#include "XTPDockingPaneManager.h"
|
|
#include "XTPDockingPaneBase.h"
|
|
#include "XTPDockingPaneBaseContainer.h"
|
|
#include "XTPDockingPane.h"
|
|
#include "XTPDockingPaneSplitterContainer.h"
|
|
#include "XTPDockingPaneTabbedContainer.h"
|
|
#include "XTPDockingPaneMiniWnd.h"
|
|
#include "XTPDockingPanePaintManager.h"
|
|
#include "XTPDockingPaneLayout.h"
|
|
#include "XTPDockingPaneAutoHidePanel.h"
|
|
#include "XTPDockingPaneSidePanel.h"
|
|
#include "XTPDockingPaneContext.h"
|
|
#include "XTPDockingPaneKeyboardHook.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define XTP_IDC_DOCKINGPANE 1300
|
|
|
|
|
|
CXTPDockingPaneManager::CXTPDockingPaneManager()
|
|
{
|
|
m_pSite = 0;
|
|
m_pLayout = 0;
|
|
|
|
m_nSplitterGap = 22;
|
|
m_nClientMargin = 0;
|
|
|
|
m_dwDefaultPaneOptions = 0;
|
|
|
|
m_bAttachingPane = FALSE;
|
|
|
|
m_bHideClient = FALSE;
|
|
m_bUseSplitterTracker = TRUE;
|
|
|
|
m_pPaintManager = NULL;
|
|
SetTheme(xtpPaneThemeDefault);
|
|
|
|
m_pImageManager = new CXTPImageManager();
|
|
|
|
m_bLockSplitters = FALSE;
|
|
|
|
m_bThemedFloatingFrames = FALSE;
|
|
|
|
m_pDockingContext = new CXTPDockingPaneContext();
|
|
m_pDockingContext->m_pManager = this;
|
|
|
|
m_bAlphaDockingContext = FALSE;
|
|
m_bShowDockingContextStickers = FALSE;
|
|
m_nDockingContextStickerStyle = xtpPaneStickerStyleVisualStudio2005;
|
|
|
|
m_bShowCloseTabButton = xtpTabNavigateButtonNone;
|
|
|
|
m_bCloseGroupOnButtonClick = FALSE;
|
|
m_bHideGroupOnButtonClick = TRUE;
|
|
m_pPreviewLayout = 0;
|
|
m_bSyncActiveFloatingFrames = TRUE;
|
|
|
|
m_captionDirection = xtpPaneCaptionHorizontal;
|
|
|
|
m_pToolTipContext = new CXTPToolTipContext();
|
|
|
|
m_pActivePane = 0;
|
|
m_bShowMaximizeButton = FALSE;
|
|
m_bLayoutCreated = FALSE;
|
|
|
|
m_bShowContentsWhileDragging = FALSE;
|
|
|
|
m_bShowSizeCursorWhileDragging = FALSE;
|
|
m_bInitialUpdateCalled = FALSE;
|
|
m_bAutoInitialUpdate = TRUE;
|
|
|
|
m_ptMinClientSize = CPoint(60, 60);
|
|
|
|
m_hwndLastFocus = NULL;
|
|
|
|
m_bStickyFloatingFrames = FALSE;
|
|
m_nStickyGap = 15;
|
|
m_nFloatingFramesOpacity = 255;
|
|
m_rcSideDockingMargin.SetRect(0, 0, 0, 0);
|
|
|
|
m_bSideDocking = FALSE;
|
|
|
|
m_bShowPanelScrollButtons = FALSE;
|
|
|
|
m_bKeyboardEnabled = xtpPaneKeyboardUnused;
|
|
|
|
HMODULE hLib = GetModuleHandle(_T("USER32"));
|
|
if (hLib)
|
|
{
|
|
m_pfnSetLayeredWindowAttributes = (PFNSETLAYEREDWINDOWATTRIBUTES)::GetProcAddress(hLib, "SetLayeredWindowAttributes");
|
|
}
|
|
|
|
XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneSplitter"), 0);
|
|
XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneTabbedContainer"), CS_DBLCLKS);
|
|
XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneManager"), 0);
|
|
XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneAutoHidePanel"), 0);
|
|
XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneMiniWnd"), CS_DBLCLKS);
|
|
XTPDrawHelpers()->RegisterWndClass(0, _T("XTPDockingPaneSidePanel"), CS_DBLCLKS);
|
|
|
|
m_pWindowSelectClass = RUNTIME_CLASS(CXTPDockingPaneWindowSelect);
|
|
|
|
OleInitialize(NULL);
|
|
|
|
EnableAutomation();
|
|
}
|
|
|
|
CXTPDockingPaneManager::~CXTPDockingPaneManager()
|
|
{
|
|
CMDTARGET_RELEASE(m_pLayout);
|
|
|
|
CMDTARGET_RELEASE(m_pActivePane);
|
|
|
|
CMDTARGET_RELEASE(m_pPaintManager);
|
|
|
|
CMDTARGET_RELEASE(m_pToolTipContext);
|
|
|
|
delete m_pDockingContext;
|
|
|
|
CMDTARGET_RELEASE(m_pImageManager);
|
|
|
|
OleUninitialize();
|
|
}
|
|
|
|
void CXTPDockingPaneManager::HideClient(BOOL bHide)
|
|
{
|
|
RecalcFrameLayout(NULL);
|
|
|
|
m_bHideClient = bHide;
|
|
m_pLayout->m_pTopContainer->OnParentContainerChanged(m_pLayout->m_pTopContainer);
|
|
|
|
RedrawPanes();
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPDockingPaneManager, CWnd)
|
|
ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
|
|
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
|
|
ON_WM_SYSCOLORCHANGE()
|
|
ON_WM_SETTINGCHANGE()
|
|
ON_MESSAGE_VOID(WM_INITIALUPDATE, OnInitialUpdate)
|
|
ON_MESSAGE(WM_GETOBJECT, OnGetObject)
|
|
END_MESSAGE_MAP()
|
|
|
|
void CXTPDockingPaneManager::OnSysColorChange()
|
|
{
|
|
RefreshXtremeColors();
|
|
|
|
m_pPaintManager->RefreshMetrics();
|
|
|
|
|
|
_Redraw();
|
|
}
|
|
|
|
void CXTPDockingPaneManager::OnSettingChange(UINT /*uFlags*/, LPCTSTR /*lpszSection*/)
|
|
{
|
|
m_pPaintManager->RefreshMetrics();
|
|
|
|
RecalcFramesLayout();
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SetFloatingFramesOpacity(int nOpacity)
|
|
{
|
|
m_nFloatingFramesOpacity = nOpacity;
|
|
|
|
POSITION pos = GetPaneStack().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = GetPaneStack().GetNext(pos);
|
|
|
|
if (pPane->GetType() == xtpPaneTypeMiniWnd)
|
|
{
|
|
((CXTPDockingPaneMiniWnd*)pPane)->UpdateWindowOpacity();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::UpdatePanes()
|
|
{
|
|
HWND hWndFocus = ::GetFocus();
|
|
|
|
if (m_hwndLastFocus == hWndFocus)
|
|
return;
|
|
|
|
m_hwndLastFocus = hWndFocus;
|
|
|
|
POSITION pos = GetPaneStack().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase *pPane = GetPaneStack().GetNext(pos);
|
|
|
|
if (pPane->GetType() == xtpPaneTypeTabbedContainer ||
|
|
pPane->GetType() == xtpPaneTypeMiniWnd ||
|
|
pPane->GetType() == xtpPaneTypeSidePanel)
|
|
{
|
|
pPane->OnFocusChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::OnInitialUpdate()
|
|
{
|
|
if (m_pSite && m_pSite->IsFrameWnd() && ((CFrameWnd*)m_pSite)->m_nIdleFlags & CFrameWnd::idleLayout)
|
|
{
|
|
RecalcFrameLayout(NULL);
|
|
}
|
|
|
|
OnIdleUpdateCmdUI(TRUE, 0L);
|
|
|
|
|
|
if (m_pLayout && m_bAutoInitialUpdate)
|
|
{
|
|
POSITION pos = m_pLayout->m_lstStack.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_pLayout->m_lstStack.GetNext(pos);
|
|
if (pPane->GetType() == xtpPaneTypeMiniWnd)
|
|
{
|
|
CXTPDockingPaneMiniWnd* pMiniFrame = (CXTPDockingPaneMiniWnd*)pPane;
|
|
|
|
if (pMiniFrame->GetSafeHwnd())
|
|
{
|
|
if (pMiniFrame->m_nIdleFlags & CFrameWnd::idleLayout)
|
|
{
|
|
pMiniFrame->RecalcLayout();
|
|
}
|
|
|
|
pMiniFrame->SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
m_bInitialUpdateCalled = TRUE;
|
|
}
|
|
|
|
|
|
LRESULT CXTPDockingPaneManager::OnIdleUpdateCmdUI(WPARAM /*wParam*/, LPARAM /*lParam*/)
|
|
{
|
|
UpdatePanes();
|
|
return 0;
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SyncPanesState()
|
|
{
|
|
POSITION pos = GetPaneList().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
XTP_DOCKINGPANE_INFO& info = GetPaneList().GetNext(pos);
|
|
CXTPDockingPaneBase* pContainer = info.pPane->m_pParentContainer;
|
|
|
|
if (info.pPane->GetDockingSite() && pContainer)
|
|
{
|
|
if (pContainer->m_pParentContainer == 0 || pContainer->m_pParentContainer->GetType() != xtpPaneTypeAutoHidePanel)
|
|
{
|
|
|
|
if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, info.pPane->GetDockingSite()))
|
|
{
|
|
info.pLastHolder = info.pFloatingHolder = pContainer;
|
|
}
|
|
else
|
|
{
|
|
info.pLastHolder = info.pDockingHolder = pContainer;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LRESULT CXTPDockingPaneManager::OnSizeParent(WPARAM, LPARAM lParam)
|
|
{
|
|
if (GetTopPane() != NULL)
|
|
{
|
|
AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
|
|
|
|
m_pLayout->OnSizeParent(m_pSite, lpLayout->rect, lpLayout);
|
|
|
|
SyncPanesState();
|
|
|
|
m_bLayoutCreated = TRUE;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CXTPDockingPaneBase* CXTPDockingPaneManager::_Clone(CXTPDockingPaneBase* pPane)
|
|
{
|
|
return pPane->Clone(m_pLayout, 0);
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::NotifyAction(XTPDockingPaneAction action, CXTPDockingPane* pPane, CXTPDockingPaneBase* pDockContainer /*= NULL*/, XTPDockingPaneDirection dockDirection /*= xtpPaneDockLeft*/)
|
|
{
|
|
if (!pPane)
|
|
return FALSE;
|
|
|
|
XTP_DOCKINGPANE_ACTION dpAction(action);
|
|
dpAction.pPane = pPane;
|
|
dpAction.pDockContainer = pDockContainer;
|
|
dpAction.dockDirection = dockDirection;
|
|
|
|
if ((pPane->GetEnabled() & xtpPaneEnableActions) == 0)
|
|
dpAction.bCancel = TRUE;
|
|
|
|
NotifyOwner(XTP_DPN_ACTION, (LPARAM)&dpAction);
|
|
|
|
return dpAction.bCancel;
|
|
}
|
|
|
|
void CXTPDockingPaneManager::LockSplitters(BOOL bLock /*= TRUE*/)
|
|
{
|
|
m_bLockSplitters = bLock;
|
|
|
|
POSITION pos = GetPaneList().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = GetPaneList().GetNext(pos);
|
|
if (pPane->GetContainer())
|
|
SAFE_CALLPTR(pPane->GetContainer()->GetContainer(), OnChildContainerChanged(pPane));
|
|
}
|
|
}
|
|
|
|
CXTPDockingPaneSidePanel* CXTPDockingPaneManager::DockSidePane(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction, CRect rc)
|
|
{
|
|
CXTPDockingPaneSidePanel* pMiniFrame = (CXTPDockingPaneSidePanel*)OnCreatePane(xtpPaneTypeSidePanel, m_pLayout);
|
|
pMiniFrame->Init(pPane, direction, rc);
|
|
|
|
SyncPanesState();
|
|
m_hwndLastFocus = 0;
|
|
|
|
RecalcFrameLayout(NULL, TRUE);
|
|
|
|
return pMiniFrame;
|
|
}
|
|
|
|
CXTPDockingPaneMiniWnd* CXTPDockingPaneManager::FloatPane(CXTPDockingPaneBase* pPane, CRect rc)
|
|
{
|
|
ASSERT(pPane->GetType() == xtpPaneTypeDockingPane || pPane->GetType() == xtpPaneTypeTabbedContainer);
|
|
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane)
|
|
{
|
|
_RemovePane(pPane);
|
|
}
|
|
else
|
|
{
|
|
pPane = pPane->Clone(m_pLayout, 0);
|
|
}
|
|
|
|
CXTPDockingPaneMiniWnd* pMiniFrame = (CXTPDockingPaneMiniWnd*)OnCreatePane(xtpPaneTypeMiniWnd, m_pLayout);
|
|
pMiniFrame->Init(pPane, rc);
|
|
|
|
SyncPanesState();
|
|
m_hwndLastFocus = 0;
|
|
|
|
return pMiniFrame;
|
|
}
|
|
|
|
CXTPDockingPane* CXTPDockingPaneManager::CreatePane(UINT nID, CRect rc, XTPDockingPaneDirection direction, CXTPDockingPaneBase* pNeighbour)
|
|
{
|
|
ASSERT(GetTopPane());
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)OnCreatePane(xtpPaneTypeDockingPane, m_pLayout);
|
|
ASSERT(pPane);
|
|
if (!pPane)
|
|
return NULL;
|
|
|
|
pPane->SetID(nID);
|
|
pPane->SetWindowRect(rc);
|
|
|
|
|
|
XTP_DOCKINGPANE_INFO pane(pPane);
|
|
GetPaneList().AddTail(pane);
|
|
|
|
_InsertPane(pPane, direction, pNeighbour);
|
|
|
|
SyncPanesState();
|
|
|
|
return pPane;
|
|
}
|
|
|
|
|
|
CXTPDockingPaneBase* CXTPDockingPaneManager::OnCreatePane(XTPDockingPaneType type, CXTPDockingPaneLayout* pLayout)
|
|
{
|
|
CXTPDockingPaneBase* pPane = NULL;
|
|
switch (type)
|
|
{
|
|
case xtpPaneTypeDockingPane:
|
|
pPane = new CXTPDockingPane(pLayout);
|
|
break;
|
|
|
|
case xtpPaneTypeSplitterContainer:
|
|
pPane = new CXTPDockingPaneSplitterContainer(pLayout);
|
|
break;
|
|
|
|
case xtpPaneTypeTabbedContainer:
|
|
pPane = new CXTPDockingPaneTabbedContainer(pLayout);
|
|
break;
|
|
|
|
case xtpPaneTypeClient:
|
|
pPane = new CXTPDockingPaneClientContainer(pLayout);
|
|
break;
|
|
|
|
case xtpPaneTypeMiniWnd:
|
|
pPane = new CXTPDockingPaneMiniWnd(pLayout);
|
|
break;
|
|
|
|
case xtpPaneTypeAutoHidePanel:
|
|
pPane = new CXTPDockingPaneAutoHidePanel(pLayout);
|
|
break;
|
|
|
|
case xtpPaneTypeSidePanel:
|
|
pPane = new CXTPDockingPaneSidePanel(pLayout);
|
|
break;
|
|
}
|
|
ASSERT(pPane);
|
|
return pPane;
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneManager::DockPane(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction, CXTPDockingPaneBase* pNeighbour)
|
|
{
|
|
if (pPane->GetType() == xtpPaneTypeSplitterContainer)
|
|
{
|
|
CXTPDockingPaneBaseList lst;
|
|
pPane->FindPane(xtpPaneTypeTabbedContainer, &lst);
|
|
|
|
if (lst.GetCount() == 1)
|
|
{
|
|
pPane = lst.GetHead();
|
|
}
|
|
}
|
|
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane)
|
|
{
|
|
_RemovePane(pPane);
|
|
}
|
|
else
|
|
{
|
|
pPane = _Clone(pPane);
|
|
}
|
|
_InsertPane(pPane, direction, pNeighbour);
|
|
|
|
m_pLayout->_FreeEmptyPanes();
|
|
m_hwndLastFocus = 0;
|
|
}
|
|
|
|
void CXTPDockingPaneManager::_RemovePane(CXTPDockingPaneBase* pPane)
|
|
{
|
|
if (!pPane)
|
|
return;
|
|
|
|
if (!pPane->m_pParentContainer)
|
|
return;
|
|
|
|
pPane->m_pParentContainer->RemovePane(pPane);
|
|
}
|
|
|
|
void CXTPDockingPaneManager::AttachPane(CXTPDockingPaneBase* pPane, CXTPDockingPaneBase* pNeighbour)
|
|
{
|
|
_AttachPane(pPane, pNeighbour);
|
|
SyncPanesState();
|
|
}
|
|
|
|
void CXTPDockingPaneManager::_AttachPane(CXTPDockingPaneBase* pPane, CXTPDockingPaneBase* pNeighbour)
|
|
{
|
|
ASSERT(pNeighbour);
|
|
if (!pNeighbour)
|
|
return;
|
|
|
|
if (pNeighbour->GetType() == xtpPaneTypeDockingPane)
|
|
{
|
|
pNeighbour = pNeighbour->m_pParentContainer;
|
|
ASSERT(pNeighbour);
|
|
}
|
|
if (!pNeighbour)
|
|
return;
|
|
ASSERT(pNeighbour->GetType() == xtpPaneTypeTabbedContainer);
|
|
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane)
|
|
{
|
|
_RemovePane(pPane);
|
|
((CXTPDockingPaneTabbedContainer*)pNeighbour)->_InsertPane((CXTPDockingPane*)pPane);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pPane->GetType() == xtpPaneTypeSplitterContainer || pPane->GetType() == xtpPaneTypeTabbedContainer);
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
pPane->FindPane(xtpPaneTypeDockingPane, &lst);
|
|
|
|
ASSERT(lst.GetCount() > 0);
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pListPane = lst.GetNext(pos);
|
|
ASSERT(pListPane->GetType() == xtpPaneTypeDockingPane);
|
|
|
|
_RemovePane(pListPane);
|
|
((CXTPDockingPaneTabbedContainer*)pNeighbour)->_InsertPane((CXTPDockingPane*)pListPane);
|
|
}
|
|
|
|
}
|
|
m_hwndLastFocus = NULL;
|
|
}
|
|
|
|
CRect CXTPDockingPaneManager::_CalculateResultDockingRect(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction, CXTPDockingPaneBase* pNeighbour)
|
|
{
|
|
if (pNeighbour == NULL)
|
|
{
|
|
pNeighbour = GetTopPane();
|
|
}
|
|
|
|
ASSERT(pNeighbour);
|
|
if (!pNeighbour)
|
|
return CRect(0, 0, 0, 0);
|
|
|
|
BOOL bHoriz = (direction == xtpPaneDockLeft || direction == xtpPaneDockRight);
|
|
|
|
if (pNeighbour == GetTopPane())
|
|
{
|
|
CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pNeighbour;
|
|
|
|
return CXTPDockingPaneSplitterContainer::_CalculateResultDockingRectChild(pSplitter, pPane, direction);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pNeighbour->m_pParentContainer);
|
|
if (!pNeighbour->m_pParentContainer)
|
|
return CRect(0, 0, 0, 0);
|
|
|
|
if (pNeighbour->m_pParentContainer->GetType() == xtpPaneTypeTabbedContainer)
|
|
{
|
|
pNeighbour = pNeighbour->m_pParentContainer;
|
|
ASSERT(pNeighbour->m_pParentContainer != NULL);
|
|
if (!pNeighbour->m_pParentContainer)
|
|
return CRect(0, 0, 0, 0);
|
|
}
|
|
|
|
ASSERT(pNeighbour->m_pParentContainer);
|
|
ASSERT(pNeighbour->m_pParentContainer->GetType() == xtpPaneTypeSplitterContainer);
|
|
|
|
CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pNeighbour->m_pParentContainer;
|
|
|
|
if (pSplitter->m_bHoriz == bHoriz)
|
|
return pSplitter->_CalculateResultDockingRectSelf(pPane, direction, pNeighbour);
|
|
|
|
return CXTPDockingPaneSplitterContainer::_CalculateResultDockingRectChild(pNeighbour, pPane, direction);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::_InsertPane(CXTPDockingPaneBase* pPane, XTPDockingPaneDirection direction, CXTPDockingPaneBase* pNeighbour)
|
|
{
|
|
ASSERT(pPane->m_pParentContainer == NULL);
|
|
|
|
if (pNeighbour == NULL || (pNeighbour->GetType() == xtpPaneTypeDockingPane &&
|
|
(IsPaneHidden((CXTPDockingPane*)pNeighbour) || IsPaneClosed((CXTPDockingPane*)pNeighbour))))
|
|
{
|
|
pNeighbour = GetTopPane();
|
|
}
|
|
|
|
ASSERT(pNeighbour);
|
|
if (!pNeighbour)
|
|
return;
|
|
|
|
CWnd* pParentFrame = pNeighbour->GetDockingSite();
|
|
ASSERT(pParentFrame != NULL);
|
|
|
|
BOOL bHoriz = (direction == xtpPaneDockLeft || direction == xtpPaneDockRight);
|
|
BOOL bAfter = (direction == xtpPaneDockRight || direction == xtpPaneDockBottom);
|
|
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)OnCreatePane(xtpPaneTypeTabbedContainer, m_pLayout);
|
|
pContainer->Init((CXTPDockingPane*)pPane, pParentFrame);
|
|
|
|
pPane = pContainer;
|
|
}
|
|
|
|
if (pNeighbour == GetTopPane())
|
|
{
|
|
CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pNeighbour;
|
|
|
|
if (pSplitter->m_bHoriz == bHoriz)
|
|
pSplitter->_InsertPane(pPane, NULL, bAfter);
|
|
else
|
|
{
|
|
CXTPDockingPaneSplitterContainer* pChildSplitter = (CXTPDockingPaneSplitterContainer*)OnCreatePane(xtpPaneTypeSplitterContainer, m_pLayout);
|
|
pChildSplitter->Init(pSplitter, bHoriz, pParentFrame);
|
|
|
|
pChildSplitter->_InsertPane(pPane, NULL, bAfter);
|
|
m_pLayout->m_pTopContainer = pChildSplitter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pNeighbour->m_pParentContainer);
|
|
if (!pNeighbour->m_pParentContainer)
|
|
return;
|
|
|
|
if (pNeighbour->m_pParentContainer->GetType() == xtpPaneTypeTabbedContainer)
|
|
{
|
|
pNeighbour = pNeighbour->m_pParentContainer;
|
|
ASSERT(pNeighbour->m_pParentContainer != NULL);
|
|
if (!pNeighbour->m_pParentContainer)
|
|
return;
|
|
}
|
|
|
|
ASSERT(pNeighbour->m_pParentContainer);
|
|
ASSERT(pNeighbour->m_pParentContainer->GetType() == xtpPaneTypeSplitterContainer);
|
|
|
|
CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pNeighbour->m_pParentContainer;
|
|
|
|
if (pSplitter->m_bHoriz == bHoriz)
|
|
{
|
|
pSplitter->_InsertPane(pPane, pNeighbour, bAfter);
|
|
}
|
|
else
|
|
{
|
|
CXTPDockingPaneSplitterContainer* pChildSplitter = (CXTPDockingPaneSplitterContainer*)OnCreatePane(xtpPaneTypeSplitterContainer, m_pLayout);
|
|
pChildSplitter->Init(pNeighbour, bHoriz, pParentFrame);
|
|
|
|
pChildSplitter->_InsertPane(pPane, pNeighbour, bAfter);
|
|
pSplitter->_Replace(pNeighbour, pChildSplitter);
|
|
}
|
|
|
|
|
|
}
|
|
RecalcFrameLayout(pNeighbour, TRUE);
|
|
}
|
|
|
|
CXTPDockingPaneBase* CXTPDockingPaneManager::_GetHolder(CXTPDockingPaneBase* pPane, BOOL bFloating)
|
|
{
|
|
POSITION pos = GetPaneList().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
XTP_DOCKINGPANE_INFO& info = GetPaneList().GetNext(pos);
|
|
if (info.pPane == pPane)
|
|
return bFloating ? info.pFloatingHolder : info.pDockingHolder;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPDockingPaneManager::ToggleAutoHide(CXTPDockingPaneBase* pPane)
|
|
{
|
|
if (pPane == NULL)
|
|
return;
|
|
|
|
if (pPane->IsHidden())
|
|
{
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane && m_bHideGroupOnButtonClick)
|
|
{
|
|
pPane = pPane->m_pParentContainer;
|
|
}
|
|
|
|
ToggleDocking(pPane);
|
|
}
|
|
else
|
|
{
|
|
HidePane(pPane);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::ToggleDocking(CXTPDockingPaneBase* pPane)
|
|
{
|
|
ASSERT(pPane);
|
|
if (!pPane)
|
|
return;
|
|
BOOL bFloating = DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pPane->GetDockingSite()) != NULL;
|
|
BOOL bHidden = pPane->IsHidden();
|
|
BOOL bDocking = !bFloating && !bHidden;
|
|
|
|
if (pPane->GetType() == xtpPaneTypeSplitterContainer || pPane->GetType() == xtpPaneTypeTabbedContainer)
|
|
{
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
pPane->FindPane(xtpPaneTypeDockingPane, &lst);
|
|
|
|
int nIDSelected = 0, nIDFocused = 0;
|
|
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pListPane = (CXTPDockingPane*)lst.GetNext(pos);
|
|
if (pListPane->IsSelected()) nIDSelected = pListPane->GetID();
|
|
if (pListPane->IsFocus()) nIDFocused = pListPane->GetID();
|
|
}
|
|
|
|
pos = lst.GetHeadPosition();
|
|
CXTPDockingPaneBase* pLastHolder = NULL;
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pListPane = (CXTPDockingPane*)lst.GetNext(pos);
|
|
|
|
CXTPDockingPaneTabbedContainer* pHolder = (CXTPDockingPaneTabbedContainer*)_GetHolder(pListPane, bDocking);
|
|
if (!_ToggleDocking(pListPane, pHolder ? pHolder : pLastHolder))
|
|
{
|
|
if (pListPane->GetID() == nIDSelected) nIDSelected = 0;
|
|
if (pListPane->GetID() == nIDFocused) nIDFocused = 0;
|
|
}
|
|
|
|
pLastHolder = pHolder ? pHolder : pListPane->GetContainer();
|
|
}
|
|
|
|
if (nIDFocused > 0)
|
|
ShowPane(nIDFocused);
|
|
else if (nIDSelected > 0)
|
|
ShowPane(nIDSelected);
|
|
}
|
|
else if (pPane->GetType() == xtpPaneTypeDockingPane)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pHolder = (CXTPDockingPaneTabbedContainer*)_GetHolder(pPane, bDocking);
|
|
_ToggleDocking((CXTPDockingPane*)pPane, pHolder);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
|
|
m_pLayout->_FreeEmptyPanes();
|
|
m_hwndLastFocus = 0;
|
|
}
|
|
|
|
|
|
|
|
BOOL CXTPDockingPaneManager::_ToggleDocking(CXTPDockingPane* pPane, CXTPDockingPaneBase* pHolder)
|
|
{
|
|
BOOL bFloating = DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pPane->GetDockingSite()) != NULL;
|
|
BOOL bHidden = pPane->IsHidden();
|
|
BOOL bDocking = !bFloating && !bHidden;
|
|
|
|
|
|
if (bFloating && (pPane->GetOptions() & xtpPaneNoDockable))
|
|
return FALSE;
|
|
|
|
if (bDocking && (pPane->GetOptions() & xtpPaneNoFloatable))
|
|
return FALSE;
|
|
|
|
if (NotifyAction(bHidden ? xtpPaneActionPinning : !bDocking ? xtpPaneActionDocking : xtpPaneActionFloating, pPane, pHolder))
|
|
return FALSE;
|
|
|
|
if (pHolder)
|
|
{
|
|
m_bAttachingPane = TRUE;
|
|
AttachPane(pPane, pHolder);
|
|
m_bAttachingPane = FALSE;
|
|
}
|
|
else
|
|
{
|
|
FloatPane(pPane, pPane->GetContainer()->GetPaneWindowRect());
|
|
}
|
|
|
|
NotifyAction(bHidden ? xtpPaneActionPinned : !bDocking ? xtpPaneActionDocked : xtpPaneActionFloated, pPane);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneManager::EnableKeyboardNavigate(DWORD options)
|
|
{
|
|
CXTPDockingPaneKeyboardHook::GetThreadState()->SetupKeyboardHook(this, options != xtpPaneKeyboardUnused);
|
|
m_bKeyboardEnabled = options;
|
|
}
|
|
|
|
bool CXTPDockingPaneManager::InstallDockingPanes(CWnd* pSite, bool bClipChildren/*=true*/)
|
|
{
|
|
#ifdef _DEBUG
|
|
// must be a valid frame window.
|
|
ASSERT(::IsWindow(pSite->GetSafeHwnd()));
|
|
|
|
// should not be initialized yet.
|
|
ASSERT(m_pLayout == 0);
|
|
ASSERT(m_pSite == 0);
|
|
#endif
|
|
|
|
if (!::IsWindow(pSite->GetSafeHwnd()) || m_pSite != 0)
|
|
{
|
|
// if the docking site is not a valid frame window handle,
|
|
// or the docking site is already initialized, return false.
|
|
return false;
|
|
}
|
|
|
|
// Frame windows must have the WS_CLIPCHILDREN and WS_CLIPSIBLINGS
|
|
// styles for panes to be drawn correctly when they are displayed
|
|
// from a hidden state. WS_CLIPSIBLINGS should already be set by
|
|
// default for most frames, however we will include it here just
|
|
// in case.
|
|
|
|
if (bClipChildren /*&& DYNAMIC_DOWNCAST(CMDIFrameWnd, pSite) == 0*/)
|
|
{
|
|
long lStyle = ::GetWindowLong(pSite->GetSafeHwnd(), GWL_STYLE);
|
|
if ((lStyle & WS_CLIPSIBLINGS) == 0 || (lStyle & WS_CLIPCHILDREN) == 0)
|
|
{
|
|
::SetWindowLong(pSite->GetSafeHwnd(), GWL_STYLE,
|
|
lStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
|
|
}
|
|
}
|
|
|
|
if (!Create(_T("XTPDockingPaneManager"), _T(""), WS_CHILD, CRect(0, 0, 0, 0), pSite, XTP_IDC_DOCKINGPANE))
|
|
return false;
|
|
|
|
m_pSite = pSite;
|
|
m_pLayout = CreateLayout();
|
|
m_pLayout->m_bUserLayout = FALSE;
|
|
|
|
|
|
CMenu* pMenu = m_pSite->GetSystemMenu(FALSE);
|
|
if (pMenu)
|
|
{
|
|
pMenu->GetMenuString(SC_MOVE, m_strMove, MF_BYCOMMAND);
|
|
if (m_strMove.IsEmpty()) m_strMove = _T("&Move");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
void CXTPDockingPaneManager::HidePane(int nID)
|
|
{
|
|
HidePane(FindPane(nID));
|
|
}
|
|
|
|
CXTPDockingPane* CXTPDockingPaneManager::FindPane(int nID) const
|
|
{
|
|
if (!m_pLayout)
|
|
return NULL;
|
|
|
|
return m_pLayout->FindPane(nID);
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::SetIcons(UINT nIDResource, const int* nIDs, int nCount, COLORREF clrMask)
|
|
{
|
|
CImageList il;
|
|
il.Create(16, 16, ILC_COLOR24 | ILC_MASK, nCount, 1);
|
|
|
|
CBitmap bmp;
|
|
bmp.LoadBitmap(nIDResource);
|
|
il.Add(&bmp, clrMask);
|
|
|
|
ASSERT(il.GetImageCount() == nCount); // Icons must be 16x16.
|
|
if (il.GetImageCount() != nCount)
|
|
return FALSE;
|
|
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
HICON hIcon = il.ExtractIcon(i);
|
|
if (nIDs[i] > 0)
|
|
{
|
|
SetIcon(nIDs[i], hIcon);
|
|
}
|
|
DestroyIcon(hIcon);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SetImageManager(CXTPImageManager* pImageManager)
|
|
{
|
|
if (pImageManager)
|
|
{
|
|
m_pImageManager->InternalRelease();
|
|
|
|
m_pImageManager = pImageManager;
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::ShowPane(CXTPDockingPane* pPane, BOOL bSetFocus /*= TRUE*/)
|
|
{
|
|
if (pPane == NULL || m_pLayout == NULL) return;
|
|
|
|
if (pPane->m_pParentContainer == NULL)
|
|
{
|
|
POSITION pos = GetPaneList().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
XTP_DOCKINGPANE_INFO& info = GetPaneList().GetNext(pos);
|
|
if (info.pPane == pPane && info.pLastHolder != NULL)
|
|
{
|
|
((CXTPDockingPaneTabbedContainer*)info.pLastHolder)->_InsertPane(pPane, bSetFocus);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
((CXTPDockingPaneTabbedContainer*)pPane->m_pParentContainer)->ShowPane(pPane, bSetFocus);
|
|
}
|
|
|
|
if (bSetFocus && m_bLayoutCreated)
|
|
{
|
|
pPane->ShowWindow(TRUE);
|
|
}
|
|
|
|
if (bSetFocus)
|
|
{
|
|
pPane->SetFocus();
|
|
}
|
|
}
|
|
|
|
LRESULT CXTPDockingPaneManager::NotifyOwner(UINT nCode, LPARAM lParam)
|
|
{
|
|
CWnd* pOwner = m_hWndOwner != NULL ? GetOwner() : m_pSite;
|
|
ASSERT_VALID(pOwner);
|
|
|
|
return pOwner->SendMessage(XTPWM_DOCKINGPANE_NOTIFY,
|
|
(WPARAM)nCode, lParam);
|
|
}
|
|
|
|
void CXTPDockingPaneManager::ClosePane(CXTPDockingPane* pPane)
|
|
{
|
|
if (pPane == NULL)
|
|
return;
|
|
|
|
pPane->InternalAddRef();
|
|
|
|
if (NotifyOwner(XTP_DPN_CLOSEPANE, (LPARAM)pPane) != XTP_ACTION_NOCLOSE)
|
|
{
|
|
SAFE_CALLPTR(pPane->m_pParentContainer, RemovePane(pPane));
|
|
}
|
|
|
|
pPane->InternalRelease();
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneManager::HidePane(CXTPDockingPaneBase* pPane)
|
|
{
|
|
if (pPane == NULL) return;
|
|
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane && m_bHideGroupOnButtonClick)
|
|
{
|
|
pPane = pPane->m_pParentContainer;
|
|
}
|
|
|
|
if (pPane == NULL || pPane->GetContainer() == NULL)
|
|
return;
|
|
|
|
if (pPane->GetContainer()->GetType() == xtpPaneTypeAutoHidePanel)
|
|
{
|
|
((CXTPDockingPaneAutoHidePanel*)pPane->GetContainer())->CloseActiveWindow();
|
|
return;
|
|
}
|
|
|
|
m_pLayout->HidePane(pPane);
|
|
|
|
RecalcFrameLayout(NULL, TRUE);
|
|
}
|
|
|
|
void CXTPDockingPaneManager::DestroyPane(CXTPDockingPane* pPane)
|
|
{
|
|
if (m_pLayout && pPane)
|
|
{
|
|
m_pLayout->DestroyPane(pPane);
|
|
RecalcFrameLayout(NULL);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::IsPaneClosed(CXTPDockingPane* pPane) const
|
|
{
|
|
return pPane == NULL || pPane->IsClosed();
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::IsPaneHidden(CXTPDockingPane* pPane) const
|
|
{
|
|
return pPane != NULL && pPane->IsHidden();
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::IsPaneSelected(CXTPDockingPane* pPane) const
|
|
{
|
|
return pPane != NULL && pPane->IsSelected();
|
|
}
|
|
|
|
void CXTPDockingPaneManager::_Redraw()
|
|
{
|
|
if (!m_hWnd)
|
|
return;
|
|
|
|
POSITION pos = GetPaneList().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = GetPaneList().GetNext(pos);
|
|
RecalcFrameLayout(pPane, TRUE);
|
|
|
|
CWnd* pFrame = pPane->GetDockingSite();
|
|
|
|
if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pFrame))
|
|
{
|
|
((CXTPDockingPaneMiniWnd*)pFrame)->OnThemedChanged();
|
|
}
|
|
|
|
if (pPane->GetContainer())
|
|
{
|
|
pPane->GetContainer()->InvalidatePane(FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SyncActiveFloatingFrames(BOOL bSyncActiveFloatingFrames)
|
|
{
|
|
if (m_bSyncActiveFloatingFrames == bSyncActiveFloatingFrames)
|
|
return;
|
|
|
|
m_bSyncActiveFloatingFrames = bSyncActiveFloatingFrames;
|
|
|
|
POSITION pos = GetPaneStack().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = GetPaneStack().GetNext(pos);
|
|
if (pPane->GetType() == xtpPaneTypeMiniWnd)
|
|
{
|
|
CXTPDockingPaneMiniWnd* pFrame = (CXTPDockingPaneMiniWnd*)pPane;
|
|
if (pFrame->m_hWnd)
|
|
{
|
|
pFrame->ModifyStyle(bSyncActiveFloatingFrames ? 0: MFS_SYNCACTIVE, bSyncActiveFloatingFrames ? MFS_SYNCACTIVE : SWP_FRAMECHANGED);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneManager::SetTheme(XTPDockingPanePaintTheme paintTheme)
|
|
{
|
|
if (m_pPaintManager != NULL)
|
|
m_pPaintManager->InternalRelease();
|
|
|
|
switch (paintTheme)
|
|
{
|
|
case xtpPaneThemeGrippered: m_pPaintManager = new CXTPDockingPaneGripperedTheme(); break;
|
|
case xtpPaneThemeWinNative: m_pPaintManager = new CXTPDockingPaneWinNativeTheme(); break;
|
|
case xtpPaneThemeWinExplorer: m_pPaintManager = new CXTPDockingPaneWinExplorerTheme(); break;
|
|
case xtpPaneThemeVisualStudio6: m_pPaintManager = new CXTPDockingPaneVisualStudio6Theme(); break;
|
|
case xtpPaneThemeVisualStudio2003: m_pPaintManager = new CXTPDockingPaneVisualStudio2003Theme(); break;
|
|
case xtpPaneThemeVisualStudio2005Beta1: m_pPaintManager = new CXTPDockingPaneVisualStudio2005Beta1Theme(); break;
|
|
case xtpPaneThemeVisualStudio2005Beta2: m_pPaintManager = new CXTPDockingPaneVisualStudio2005Beta2Theme(); break;
|
|
case xtpPaneThemeVisualStudio2005: m_pPaintManager = new CXTPDockingPaneVisualStudio2005Theme(); break;
|
|
case xtpPaneThemeVisualStudio2008: m_pPaintManager = new CXTPDockingPaneVisualStudio2008Theme(); break;
|
|
case xtpPaneThemeVisualStudio2010: m_pPaintManager = new CXTPDockingPaneVisualStudio2010Theme(); break;
|
|
case xtpPaneThemeOffice2002Visio: m_pPaintManager = new CXTPDockingPaneOffice2002VisioTheme(); break;
|
|
case xtpPaneThemeOffice2003: m_pPaintManager = new CXTPDockingPaneOffice2003Theme(); break;
|
|
case xtpPaneThemeOffice2003Visio: m_pPaintManager = new CXTPDockingPaneOffice2003VisioTheme(); break;
|
|
case xtpPaneThemeOffice2003Outlook: m_pPaintManager = new CXTPDockingPaneOffice2003OutlookTheme(); break;
|
|
case xtpPaneThemeResource: m_pPaintManager = new CXTPDockingPaneOffice2007Theme(); break;
|
|
case xtpPaneThemeOffice2007Visio: m_pPaintManager = new CXTPDockingPaneOffice2007VisioTheme(); break;
|
|
case xtpPaneThemeOffice2007Outlook: m_pPaintManager = new CXTPDockingPaneOffice2007OutlookTheme(); break;
|
|
case xtpPaneThemeOffice2007Word: m_pPaintManager = new CXTPDockingPaneOffice2007WordTheme(); break;
|
|
default: m_pPaintManager = new CXTPDockingPaneDefaultTheme(); break;
|
|
}
|
|
|
|
m_pPaintManager->m_themeCurrent = paintTheme;
|
|
|
|
if (paintTheme == xtpPaneThemeVisualStudio2010)
|
|
m_nDockingContextStickerStyle = xtpPaneStickerStyleVisualStudio2010;
|
|
else if (paintTheme == xtpPaneThemeVisualStudio2008)
|
|
m_nDockingContextStickerStyle = xtpPaneStickerStyleVisualStudio2008;
|
|
else
|
|
m_nDockingContextStickerStyle = xtpPaneStickerStyleVisualStudio2005;
|
|
|
|
m_pPaintManager->RefreshMetrics();
|
|
|
|
_Redraw();
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SetCustomTheme(CXTPDockingPanePaintManager* pTheme)
|
|
{
|
|
ASSERT(pTheme);
|
|
if (!pTheme)
|
|
return;
|
|
|
|
if (m_pPaintManager != NULL)
|
|
m_pPaintManager->InternalRelease();
|
|
|
|
m_pPaintManager = pTheme;
|
|
m_pPaintManager->m_themeCurrent = xtpPaneThemeCustom;
|
|
m_pPaintManager->RefreshMetrics();
|
|
|
|
_Redraw();
|
|
}
|
|
|
|
|
|
XTPDockingPanePaintTheme CXTPDockingPaneManager::GetCurrentTheme() const
|
|
{
|
|
return m_pPaintManager->m_themeCurrent;
|
|
}
|
|
|
|
CXTPDockingPaneLayout* CXTPDockingPaneManager::CreateLayout()
|
|
{
|
|
return new CXTPDockingPaneLayout(this);
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneManager::GetLayout(CXTPDockingPaneLayout* pLayout) const
|
|
{
|
|
ASSERT(pLayout);
|
|
if (!pLayout)
|
|
return;
|
|
|
|
pLayout->Copy(m_pLayout);
|
|
}
|
|
|
|
void CXTPDockingPaneManager::_DetachAll()
|
|
{
|
|
POSITION pos = GetPaneList().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = GetPaneList().GetNext(pos);
|
|
pPane->Detach();
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SetLayout(const CXTPDockingPaneLayout* pLayout)
|
|
{
|
|
ASSERT(pLayout);
|
|
|
|
if (!pLayout || !pLayout->IsValid())
|
|
return;
|
|
|
|
_DetachAll();
|
|
|
|
m_pLayout->Copy(pLayout);
|
|
_Redraw();
|
|
}
|
|
|
|
void CXTPDockingPaneManager::DestroyAll()
|
|
{
|
|
if (m_pLayout)
|
|
{
|
|
m_pLayout->InternalRelease();
|
|
m_pLayout = CreateLayout();
|
|
m_pLayout->m_bUserLayout = FALSE;
|
|
}
|
|
}
|
|
void CXTPDockingPaneManager::CloseAll()
|
|
{
|
|
CXTPDockingPaneInfoList& paneList = GetPaneList();
|
|
POSITION pos = paneList.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = paneList.GetNext(pos);
|
|
pPane->Close();
|
|
}
|
|
}
|
|
|
|
|
|
CXTPDockingPaneBaseList& CXTPDockingPaneManager::GetPaneStack() const
|
|
{
|
|
return m_pLayout->m_lstStack;
|
|
}
|
|
|
|
CXTPDockingPaneInfoList& CXTPDockingPaneManager::GetPaneList() const
|
|
{
|
|
return m_pLayout->m_lstPanes;
|
|
}
|
|
|
|
CXTPDockingPaneBase* CXTPDockingPaneManager::GetClientPane() const
|
|
{
|
|
return m_pLayout ? m_pLayout->m_pClient : NULL;
|
|
}
|
|
|
|
CXTPDockingPaneBase* CXTPDockingPaneManager::GetTopPane() const
|
|
{
|
|
return m_pLayout ? m_pLayout->m_pTopContainer : NULL;
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SetIcon(UINT nID, const CXTPImageManagerIconHandle& hIcon)
|
|
{
|
|
m_pImageManager->SetIcon(hIcon, nID, 0, xtpImageNormal);
|
|
}
|
|
|
|
CXTPImageManagerIcon* CXTPDockingPaneManager::GetIcon(UINT nID, int nWidth) const
|
|
{
|
|
return m_pImageManager->GetImage(nID, nWidth);
|
|
}
|
|
|
|
void CXTPDockingPaneManager::ClearIconMap()
|
|
{
|
|
m_pImageManager->RemoveAll();
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SetThemedFloatingFrames(BOOL bThemedFloatingFrames)
|
|
{
|
|
m_bThemedFloatingFrames = bThemedFloatingFrames;
|
|
|
|
if (!m_pLayout)
|
|
return;
|
|
|
|
POSITION pos = GetPaneList().GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = GetPaneList().GetNext(pos);
|
|
CWnd* pFrame = pPane->GetDockingSite();
|
|
|
|
if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pFrame))
|
|
{
|
|
((CXTPDockingPaneMiniWnd*)pFrame)->OnThemedChanged();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CXTPDockingPaneManager::SetAnimationDelay(double dAnimationDelay /*= -1*/, int nAnimationDuration /*= 128*/, int nAnimationInterval /*= 16*/)
|
|
{
|
|
CXTPDockingPaneAutoHideWnd::m_dAnimationDelay = dAnimationDelay;
|
|
CXTPDockingPaneAutoHideWnd::m_nAnimationDuration = nAnimationDuration;
|
|
CXTPDockingPaneAutoHideWnd::m_nAnimationInterval = nAnimationInterval;
|
|
}
|
|
double CXTPDockingPaneManager::GetAnimationDelay(int* pAnimationDuration /*= NULL*/, int* pAnimationInterval /*= NULL*/) const
|
|
{
|
|
if (pAnimationDuration) *pAnimationDuration = CXTPDockingPaneAutoHideWnd::m_nAnimationDuration;
|
|
if (pAnimationInterval) *pAnimationInterval = CXTPDockingPaneAutoHideWnd::m_nAnimationInterval;
|
|
|
|
return CXTPDockingPaneAutoHideWnd::m_dAnimationDelay;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::IsLayoutRTL() const
|
|
{
|
|
return (GetSite()->GetExStyle() & WS_EX_LAYOUTRTL) != 0;
|
|
}
|
|
|
|
XTPDockingPaneDirection CXTPDockingPaneManager::GetRTLDirection(XTPDockingPaneDirection direction) const
|
|
{
|
|
if (IsLayoutRTL())
|
|
{
|
|
if (direction == xtpPaneDockLeft) direction = xtpPaneDockRight;
|
|
else if (direction == xtpPaneDockRight) direction = xtpPaneDockLeft;
|
|
}
|
|
return direction;
|
|
}
|
|
|
|
XTPDockingPaneDirection CXTPDockingPaneManager::GetPaneDirection(const CXTPDockingPaneBase* pPane) const
|
|
{
|
|
ASSERT(m_pLayout);
|
|
if (!m_pLayout)
|
|
return xtpPaneDockTop;
|
|
|
|
return m_pLayout->_GetPaneDirection(pPane);
|
|
}
|
|
|
|
void CXTPDockingPaneManager::SetDockingContext(CXTPDockingPaneContext* pDockingContext)
|
|
{
|
|
delete m_pDockingContext;
|
|
m_pDockingContext = pDockingContext;
|
|
m_pDockingContext->m_pManager = this;
|
|
}
|
|
|
|
|
|
|
|
void CXTPDockingPaneManager::NormalizeSplitters()
|
|
{
|
|
CXTPDockingPaneBaseList& lst = GetPaneStack();
|
|
POSITION pos = lst.GetHeadPosition();
|
|
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = lst.GetNext(pos);
|
|
|
|
if (pPane->GetType() == xtpPaneTypeSplitterContainer)
|
|
{
|
|
((CXTPDockingPaneSplitterContainer*)pPane)->NormalizeDockingSize();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::RecalcFramesLayout()
|
|
{
|
|
CXTPDockingPaneBaseList& lst = GetPaneStack();
|
|
POSITION pos = lst.GetHeadPosition();
|
|
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = lst.GetNext(pos);
|
|
|
|
if (pPane->GetType() == xtpPaneTypeMiniWnd)
|
|
{
|
|
CXTPDockingPaneMiniWnd* pMiniWnd = (CXTPDockingPaneMiniWnd*)pPane;
|
|
|
|
if (pMiniWnd->m_hWnd && pMiniWnd->GetStyle() & WS_VISIBLE)
|
|
{
|
|
pMiniWnd->RecalcLayout(TRUE);
|
|
pMiniWnd->MoveWindow(CXTPWindowRect(pMiniWnd));
|
|
}
|
|
}
|
|
}
|
|
RecalcFrameLayout(NULL);
|
|
}
|
|
|
|
void CXTPDockingPaneManager::EnsureVisible(CXTPDockingPaneBase* pPane)
|
|
{
|
|
if (!pPane)
|
|
return;
|
|
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane)
|
|
{
|
|
ShowPane((CXTPDockingPane*)pPane, FALSE);
|
|
pPane = pPane->GetContainer();
|
|
}
|
|
|
|
if (pPane->GetType() == xtpPaneTypeTabbedContainer)
|
|
{
|
|
((CXTPDockingPaneTabbedContainer*)pPane)->Show(FALSE);
|
|
}
|
|
|
|
CWnd* pSite = pPane->GetDockingSite();
|
|
if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pSite))
|
|
{
|
|
pSite->BringWindowToTop();
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::OnSetPreviewMode(BOOL bPreview)
|
|
{
|
|
|
|
// Toggle Docking Panes.
|
|
if (bPreview)
|
|
{
|
|
ASSERT(m_pPreviewLayout == NULL);
|
|
m_pPreviewLayout = CreateLayout();
|
|
GetLayout(m_pPreviewLayout);
|
|
CloseAll();
|
|
}
|
|
else
|
|
{
|
|
ASSERT(m_pPreviewLayout != NULL);
|
|
SetLayout(m_pPreviewLayout);
|
|
|
|
CMDTARGET_RELEASE(m_pPreviewLayout);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::OnActivatePane(BOOL bActive, CXTPDockingPane* pPane)
|
|
{
|
|
if (bActive && m_pActivePane != pPane)
|
|
{
|
|
if (m_pActivePane)
|
|
{
|
|
NotifyAction(xtpPaneActionDeactivated, m_pActivePane);
|
|
m_pActivePane->InternalRelease();
|
|
}
|
|
|
|
m_pActivePane = pPane;
|
|
|
|
if (m_pActivePane)
|
|
{
|
|
m_pActivePane->InternalAddRef();
|
|
NotifyAction(xtpPaneActionActivated, m_pActivePane);
|
|
}
|
|
}
|
|
else if (!bActive && pPane && m_pActivePane == pPane)
|
|
{
|
|
m_pActivePane = 0;
|
|
NotifyAction(xtpPaneActionDeactivated, pPane);
|
|
|
|
pPane->InternalRelease();
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
if (pPX->IsStoring())
|
|
{
|
|
CXTPDockingPaneLayout layoutNormal(this);
|
|
GetLayout(&layoutNormal);
|
|
layoutNormal.DoPropExchange(pPX);
|
|
}
|
|
else
|
|
{
|
|
CXTPDockingPaneLayout layoutNormal(this);
|
|
if (!layoutNormal.DoPropExchange(pPX))
|
|
return FALSE;
|
|
SetLayout(&layoutNormal);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneManager::RecalcFrameLayout(CXTPDockingPaneBase* pPane, BOOL bDelay)
|
|
{
|
|
CWnd* pSite = pPane ? pPane->GetDockingSite() : GetSite();
|
|
if (!pSite || !IsWindow(pSite->GetSafeHwnd()))
|
|
return;
|
|
|
|
CFrameWnd* pFrame = pSite->IsFrameWnd() ? (CFrameWnd*)pSite : NULL;
|
|
|
|
if (pFrame)
|
|
{
|
|
if (bDelay)
|
|
{
|
|
pFrame->DelayRecalcLayout(FALSE);
|
|
pFrame->PostMessage(WM_IDLEUPDATECMDUI);
|
|
}
|
|
else
|
|
pFrame->RecalcLayout(FALSE);
|
|
}
|
|
else
|
|
{
|
|
CXTPClientRect rc(pSite);
|
|
if (bDelay)
|
|
{
|
|
MSG msg;
|
|
if (PeekMessage(&msg, pSite->GetSafeHwnd(), WM_SIZE, WM_SIZE, PM_NOREMOVE))
|
|
return;
|
|
|
|
pSite->PostMessage(WM_SIZE, 0, MAKELPARAM(rc.Width(), rc.Height()));
|
|
}
|
|
else
|
|
pSite->SendMessage(WM_SIZE, 0, MAKELPARAM(rc.Width(), rc.Height()));
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneManager::_TrackPopupContextMenu(CXTPDockingPane* pPane)
|
|
{
|
|
CPoint pt(0, 0);
|
|
CXTPDockingPaneBase* pContainer = pPane->GetContainer();
|
|
|
|
if (pPane->IsFloating())
|
|
{
|
|
pPane->GetDockingSite()->ClientToScreen(&pt);
|
|
pContainer = ((CXTPDockingPaneMiniWnd*)pPane->GetDockingSite())->GetTopPane();
|
|
}
|
|
else
|
|
{
|
|
CRect rc = pContainer->GetPaneWindowRect();
|
|
GetPaintManager()->AdjustCaptionRect((CXTPDockingPaneTabbedContainer*)pContainer, rc);
|
|
pt = rc.TopLeft();
|
|
}
|
|
|
|
CMenu menu;
|
|
menu.CreatePopupMenu();
|
|
menu.InsertMenu(0, MF_BYPOSITION | MF_STRING, SC_MOVE, m_strMove);
|
|
|
|
BOOL nCommand = TrackPopupMenu(menu, TPM_RETURNCMD, pt.x, pt.y, 0, GetSite()->GetSafeHwnd(), NULL);
|
|
|
|
if (nCommand == SC_MOVE)
|
|
{
|
|
CXTPDockingPaneContext* pContext = GetDockingContext();
|
|
pContext->Drag(pContainer, CPoint(-1, -1));
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::ActivateNextPane(CXTPDockingPane* pPaneActive, BOOL bForward)
|
|
{
|
|
if (!m_pLayout)
|
|
return FALSE;
|
|
|
|
CXTPDockingPaneInfoList& paneList = m_pLayout->GetPaneList();
|
|
if (paneList.IsEmpty())
|
|
return FALSE;
|
|
|
|
BOOL bActive = (pPaneActive != NULL);
|
|
|
|
POSITION posFirst = bForward ? paneList.GetHeadPosition() : paneList.GetTailPosition();
|
|
POSITION pos = posFirst;
|
|
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = bForward ? paneList.GetNext(pos) : paneList.GetPrev(pos);
|
|
|
|
if (pos == NULL && bActive)
|
|
{
|
|
pos = posFirst;
|
|
bActive = FALSE;
|
|
}
|
|
|
|
if (!pPaneActive)
|
|
{
|
|
if ((pPane->GetEnabled() & xtpPaneEnableClient) == 0)
|
|
continue;
|
|
|
|
ShowPane(pPane);
|
|
return TRUE;
|
|
}
|
|
else if (pPane == pPaneActive)
|
|
{
|
|
pPaneActive = NULL;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneManager::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
|
{
|
|
if (message == WM_DESTROY && m_bKeyboardEnabled)
|
|
{
|
|
m_bKeyboardEnabled = FALSE;
|
|
CXTPDockingPaneKeyboardHook::GetThreadState()->SetupKeyboardHook(this, FALSE);
|
|
}
|
|
|
|
if (message == WM_SYSCOMMAND && wParam == SC_KEYMENU && LOWORD(lParam) == TEXT('-'))
|
|
{
|
|
CXTPDockingPane* pPane = GetActivePane();
|
|
if (pPane && !pPane->IsClosed() && !pPane->IsHidden())
|
|
{
|
|
_TrackPopupContextMenu(pPane);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (message == WM_SYSCOMMAND && (wParam == SC_NEXTWINDOW || wParam == SC_PREVWINDOW))
|
|
{
|
|
return ActivateNextPane(GetActivePane(), wParam == SC_NEXTWINDOW);
|
|
}
|
|
|
|
return CWnd::OnWndMsg(message, wParam, lParam, pResult);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Accessible
|
|
|
|
CCmdTarget* CXTPDockingPaneManager::GetAccessible()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneManager::GetAccessibleParent(IDispatch* FAR* ppdispParent)
|
|
{
|
|
if (GetSafeHwnd())
|
|
{
|
|
return AccessibleObjectFromWindow(GetSafeHwnd(), OBJID_WINDOW, IID_IDispatch, (void**)ppdispParent);
|
|
}
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneManager::GetAccessibleChildCount(long FAR* pChildCount)
|
|
{
|
|
if (pChildCount == 0)
|
|
return E_INVALIDARG;
|
|
|
|
*pChildCount = (long)m_pLayout->GetPaneList().GetCount();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneManager::GetAccessibleChild(VARIANT varChild, IDispatch* FAR* ppdispChild)
|
|
{
|
|
*ppdispChild = NULL;
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
if (nChild > 0 && nChild <= m_pLayout->GetPaneList().GetCount())
|
|
{
|
|
CXTPDockingPane* pPane = m_pLayout->GetPaneList().GetAt(m_pLayout->GetPaneList().FindIndex(nChild - 1));
|
|
if (pPane)
|
|
{
|
|
*ppdispChild = pPane->GetIDispatch(TRUE);
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneManager::GetAccessibleName(VARIANT varChild, BSTR* pszName)
|
|
{
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
if (nChild == CHILDID_SELF || nChild == -1)
|
|
{
|
|
*pszName = SysAllocString(L"XTPDockingPaneManager");
|
|
return S_OK;
|
|
}
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneManager::GetAccessibleRole(VARIANT varChild, VARIANT* pvarRole)
|
|
{
|
|
pvarRole->vt = VT_EMPTY;
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
if (nChild == CHILDID_SELF)
|
|
{
|
|
pvarRole->vt = VT_I4;
|
|
pvarRole->lVal = ROLE_SYSTEM_PROPERTYPAGE;
|
|
return S_OK;
|
|
}
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneManager::GetAccessibleState(VARIANT varChild, VARIANT* pvarState)
|
|
{
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
if (nChild == CHILDID_SELF || nChild == -1)
|
|
{
|
|
pvarState->vt = VT_I4;
|
|
pvarState->lVal = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
HRESULT CXTPDockingPaneManager::AccessibleLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT /*varChild*/)
|
|
{
|
|
*pxLeft = *pyTop = 0;
|
|
*pcxWidth = *pcyHeight = 10;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneManager::AccessibleHitTest(long /*xLeft*/, long /*yTop*/, VARIANT* /*pvarID*/)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
|
|
LRESULT CXTPDockingPaneManager::OnGetObject(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (((LONG)lParam) != OBJID_CLIENT)
|
|
return (LRESULT)Default();
|
|
|
|
LPUNKNOWN lpUnknown = GetInterface(&IID_IAccessible);
|
|
if (!lpUnknown)
|
|
return E_FAIL;
|
|
|
|
return LresultFromObject(IID_IAccessible, wParam, lpUnknown);
|
|
}
|
|
|
|
BEGIN_INTERFACE_MAP(CXTPDockingPaneManager, CCmdTarget)
|
|
INTERFACE_PART(CXTPDockingPaneManager, IID_IAccessible, ExternalAccessible)
|
|
END_INTERFACE_MAP()
|