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.
1788 lines
40 KiB
C++
1788 lines
40 KiB
C++
// XTPDockingPaneTabbedContainer.cpp : implementation of the CXTPDockingPaneTabbedContainer 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 "Resource.h"
|
|
|
|
#include "Common/XTPResourceManager.h"
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPToolTipContext.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
#include "Common/XTPColorManager.h"
|
|
|
|
#include "TabManager/XTPTabManager.h"
|
|
#include "TabManager/XTPTabPaintManager.h"
|
|
|
|
#include "XTPDockingPaneDefines.h"
|
|
#include "XTPDockingPaneBase.h"
|
|
#include "XTPDockingPaneBaseContainer.h"
|
|
#include "XTPDockingPaneTabbedContainer.h"
|
|
#include "XTPDockingPane.h"
|
|
#include "XTPDockingPaneContext.h"
|
|
#include "XTPDockingPaneManager.h"
|
|
#include "XTPDockingPanePaintManager.h"
|
|
#include "XTPDockingPaneLayout.h"
|
|
#include "XTPDockingPaneAutoHidePanel.h"
|
|
#include "XTPDockingPaneMiniWnd.h"
|
|
#include "XTPDockingPaneSidePanel.h"
|
|
#include "XTPDockingPaneSplitterContainer.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CTabManagerDropTarget
|
|
|
|
class CXTPDockingPaneTabbedContainer::CContainerDropTarget : public COleDropTarget
|
|
{
|
|
public:
|
|
CContainerDropTarget()
|
|
{
|
|
m_ptDragLastPoint = CPoint(-1, -1);
|
|
m_dwDragLastTick = 0;
|
|
}
|
|
|
|
void OnDragLeave(CWnd* /*pWnd*/)
|
|
{
|
|
m_dwDragLastTick = 0;
|
|
m_ptDragLastPoint = CPoint(-1, -1);
|
|
}
|
|
|
|
virtual DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* /*pDataObject*/, DWORD /*dwKeyState*/, CPoint point)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pControl = (CXTPDockingPaneTabbedContainer*)pWnd;
|
|
ASSERT_VALID(pControl);
|
|
|
|
if (!pControl->GetPaintManager()->m_bSelectOnDragOver)
|
|
return DROPEFFECT_NONE;
|
|
|
|
if (m_dwDragLastTick != (DWORD)-1 && pControl->GetPaintManager()->m_bSelectOnDragOver == 2)
|
|
{
|
|
DWORD dwTick = GetTickCount();
|
|
|
|
if (point != m_ptDragLastPoint)
|
|
{
|
|
m_dwDragLastTick = dwTick;
|
|
m_ptDragLastPoint = point;
|
|
}
|
|
|
|
if (dwTick - m_dwDragLastTick > CXTPTabPaintManager::m_nSelectOnDragOverDelay)
|
|
{
|
|
m_dwDragLastTick = (DWORD)-1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CXTPTabManagerItem* pItem = pControl->CXTPTabManager::HitTest(point);
|
|
|
|
if (pItem)
|
|
{
|
|
CXTPDockingPane* pPane = pControl->GetItemPane(pItem->GetIndex());
|
|
if (pControl->GetSelected() != pPane)
|
|
{
|
|
pControl->SelectPane(pPane, FALSE, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_dwDragLastTick = 0;
|
|
}
|
|
}
|
|
|
|
return DROPEFFECT_NONE;
|
|
}
|
|
|
|
protected:
|
|
DWORD m_dwDragHoverMode;
|
|
DWORD m_dwDragLastTick;
|
|
CPoint m_ptDragLastPoint;
|
|
};
|
|
|
|
// CXTPDockingPaneTabbedContainer
|
|
|
|
void CXTPDockingPaneTabbedContainer::RedrawControl(LPCRECT lpRect, BOOL /*bAnimate*/)
|
|
{
|
|
if (!m_nLockReposition)
|
|
{
|
|
if (GetSafeHwnd()) InvalidateRect(lpRect, FALSE);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::Reposition()
|
|
{
|
|
if (!m_nLockReposition)
|
|
{
|
|
InvalidatePane(FALSE);
|
|
}
|
|
|
|
}
|
|
|
|
CXTPTabPaintManager* CXTPDockingPaneTabbedContainer::GetPaintManager() const
|
|
{
|
|
return CXTPDockingPaneBase::GetPaintManager()->GetTabPaintManager();
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::SetPaintManager(CXTPTabPaintManager* /*pPaintManager*/)
|
|
{
|
|
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::DrawIcon(CDC* pDC, CPoint pt, CXTPTabManagerItem* pItem, BOOL bDraw, CSize& szIcon) const
|
|
{
|
|
if (!pItem)
|
|
return TRUE;
|
|
|
|
if (!CXTPDockingPaneBase::GetPaintManager()->GetTabPaintManager()->m_bShowIcons)
|
|
return FALSE;
|
|
|
|
CXTPImageManagerIcon* pImage = ((CXTPDockingPane*)pItem->GetData())->GetIcon(szIcon.cx);
|
|
|
|
if (!pImage)
|
|
return FALSE;
|
|
|
|
if (!bDraw)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
pItem->DrawImage(pDC, CRect(pt, szIcon), pImage);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPDockingPaneTabbedContainer, CWnd)
|
|
|
|
CXTPDockingPaneTabbedContainer::CXTPDockingPaneTabbedContainer(CXTPDockingPaneLayout* pLayout)
|
|
: CXTPDockingPaneBaseContainer(xtpPaneTypeTabbedContainer, pLayout)
|
|
{
|
|
|
|
m_pSelectedPane = 0;
|
|
m_pTrackingPane = 0;
|
|
|
|
m_nLockReposition = 0;
|
|
|
|
m_bActive = FALSE;
|
|
m_bTitleVisible = TRUE;
|
|
m_bDelayRedraw = FALSE;
|
|
|
|
m_pCaptionButtons = new CXTPDockingPaneCaptionButtons();
|
|
m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_CLOSE, this));
|
|
m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_MAXIMIZE, this));
|
|
m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_RESTORE, this));
|
|
m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_AUTOHIDE, this));
|
|
m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_MENU, this));
|
|
|
|
m_pDropTarget = new CContainerDropTarget();
|
|
m_bMaximized = FALSE;
|
|
|
|
m_bEnsureSelectedTab = FALSE;
|
|
|
|
EnableAutomation();
|
|
|
|
}
|
|
|
|
CXTPDockingPaneCaptionButton* CXTPDockingPaneTabbedContainer::GetCloseButton() const
|
|
{
|
|
return FindCaptionButton(XTP_IDS_DOCKINGPANE_CLOSE);
|
|
}
|
|
CXTPDockingPaneCaptionButton* CXTPDockingPaneTabbedContainer::GetPinButton() const
|
|
{
|
|
return FindCaptionButton(XTP_IDS_DOCKINGPANE_AUTOHIDE);
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneTabbedContainer::Init(CXTPDockingPane* pPane, CWnd* pFrame)
|
|
{
|
|
ASSERT(pPane);
|
|
if (!pPane)
|
|
return;
|
|
|
|
m_pDockingSite = pFrame;
|
|
m_szDocking = pPane->m_szDocking;
|
|
m_rcWindow = pPane->m_rcWindow;
|
|
|
|
_InsertPane(pPane);
|
|
SelectPane(pPane);
|
|
}
|
|
|
|
CXTPDockingPaneTabbedContainer::~CXTPDockingPaneTabbedContainer()
|
|
{
|
|
if (m_hWnd) DestroyWindow();
|
|
|
|
delete m_pDropTarget;
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::SetDockingSite(CWnd* pFrame)
|
|
{
|
|
m_pDockingSite = pFrame;
|
|
|
|
if (m_hWnd && !pFrame->GetSafeHwnd())
|
|
{
|
|
pFrame = GetDockingPaneManager()->GetSite();
|
|
}
|
|
|
|
if (m_hWnd)
|
|
{
|
|
if (GetParent() != pFrame) CWnd::SetParent(pFrame);
|
|
}
|
|
|
|
POSITION pos = GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)GetNext(pos);
|
|
pPane->SetDockingSite(m_pDockingSite);
|
|
}
|
|
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsTabsVisible() const
|
|
{
|
|
return m_hWnd && !DYNAMIC_DOWNCAST(CXTPDockingPaneAutoHideWnd, GetParent())
|
|
&& (GetItemCount() > 1 || CXTPDockingPaneBase::GetPaintManager()->m_bDrawSingleTab);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::InvalidatePane(BOOL bSelectionChanged)
|
|
{
|
|
if (!GetSafeHwnd())
|
|
return;
|
|
|
|
if (m_pParentContainer == 0)
|
|
return;
|
|
|
|
if (m_nLockReposition)
|
|
return;
|
|
|
|
m_nLockReposition += 1;
|
|
OnTabsChanged();
|
|
m_nLockReposition -= 1;
|
|
|
|
CRect rect = m_rcWindow;
|
|
CXTPDockingPaneBase::GetPaintManager()->AdjustClientRect(this, rect, TRUE);
|
|
|
|
if (bSelectionChanged)
|
|
{
|
|
POSITION pos = GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)GetNext(pos);
|
|
CRect rcPane = m_pSelectedPane == pPane ? rect : CRect(0, 0, 0, 0);
|
|
pPane->OnSizeParent(m_pDockingSite, rcPane, 0);
|
|
}
|
|
}
|
|
Invalidate(FALSE);
|
|
|
|
m_pParentContainer->InvalidatePane(bSelectionChanged);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnSizeParent(CWnd* pParent, CRect rect, LPVOID lParam)
|
|
{
|
|
AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
|
|
|
|
ASSERT(!IsEmpty());
|
|
|
|
SetDockingSite(pParent);
|
|
m_rcWindow = rect;
|
|
|
|
if (lpLayout == 0 || lpLayout->hDWP != NULL)
|
|
{
|
|
CRect rectOld;
|
|
::GetWindowRect(m_hWnd, rectOld);
|
|
HWND hWndParent = ::GetParent(m_hWnd);
|
|
::ScreenToClient(hWndParent, &rectOld.TopLeft());
|
|
::ScreenToClient(hWndParent, &rectOld.BottomRight());
|
|
if (rectOld != rect || m_bDelayRedraw)
|
|
{
|
|
SetWindowPos(&CWnd::wndBottom, rect.left, rect.top, rect.Width(), rect.Height(), 0);
|
|
Invalidate(FALSE);
|
|
m_bDelayRedraw = FALSE;
|
|
}
|
|
else
|
|
{
|
|
SetWindowPos(&CWnd::wndBottom, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE);
|
|
}
|
|
|
|
m_nLockReposition += 1;
|
|
OnTabsChanged();
|
|
m_nLockReposition -= 1;
|
|
|
|
GetPinButton()->SetState(IsHidden() ? xtpPanePinVisible | xtpPanePinPushed: DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, pParent) == 0 ? xtpPanePinVisible : 0);
|
|
|
|
CXTPDockingPaneBase::GetPaintManager()->AdjustClientRect(this, rect, TRUE);
|
|
|
|
POSITION pos = GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)GetNext(pos);
|
|
|
|
CRect rcPane = m_pSelectedPane == pPane ? rect : CRect(0, 0, 0, 0);
|
|
pPane->OnSizeParent(pParent, rcPane, lParam);
|
|
}
|
|
|
|
if (m_bEnsureSelectedTab)
|
|
{
|
|
m_bEnsureSelectedTab = FALSE;
|
|
EnsureSelectedTabVisible();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::EnsureSelectedTabVisible()
|
|
{
|
|
if (!m_hWnd)
|
|
return;
|
|
|
|
m_nLockReposition += 1;
|
|
CXTPTabManager::EnsureVisible(GetPaneTab(m_pSelectedPane));
|
|
CRect rect = m_rcWindow;
|
|
CXTPDockingPaneBase::GetPaintManager()->AdjustClientRect(this, rect, TRUE);
|
|
m_nLockReposition -= 1;
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnTabsChanged()
|
|
{
|
|
if (!m_hWnd)
|
|
return;
|
|
|
|
m_nLockReposition += 1;
|
|
|
|
DeleteAllItems();
|
|
|
|
m_bCloseItemButton = GetDockingPaneManager()->m_bShowCloseTabButton;
|
|
|
|
POSITION pos = GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)GetNext(pos);
|
|
|
|
CXTPTabManagerItem* pItem = AddItem(GetItemCount());
|
|
if (m_pSelectedPane == pPane) SetSelectedItem(pItem);
|
|
|
|
pItem->SetCaption(pPane->GetTabCaption());
|
|
pItem->SetColor(pPane->GetItemColor());
|
|
pItem->SetTooltip(pPane->GetTitle());
|
|
pItem->SetEnabled(pPane->GetEnabled() & xtpPaneEnableClient);
|
|
pItem->SetClosable((pPane->GetOptions() & xtpPaneNoCloseable) == 0);
|
|
|
|
pItem->SetData((DWORD_PTR)pPane);
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
m_pCaptionButtons->CheckForMouseOver(CPoint(-1, -1));
|
|
|
|
m_nLockReposition -= 1;
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::CreateContainer()
|
|
{
|
|
SAFE_CALLPTR(m_pParentContainer, CreateContainer());
|
|
|
|
if (!m_hWnd)
|
|
{
|
|
Create(_T("XTPDockingPaneTabbedContainer"), _T(""), WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), GetDockingSite(), 0);
|
|
m_pDropTarget->Register(this);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::_InsertPane(CXTPDockingPane* pPane, BOOL bSetFocus)
|
|
{
|
|
ASSERT(m_pLayout);
|
|
if (!m_pLayout)
|
|
return;
|
|
|
|
if (!m_hWnd && !m_pLayout->IsUserLayout())
|
|
{
|
|
CreateContainer();
|
|
}
|
|
|
|
m_lstPanes.AddTail(pPane);
|
|
|
|
pPane->SetParentContainer(this);
|
|
pPane->SetDockingSite(GetDockingSite());
|
|
|
|
m_bDelayRedraw = TRUE;
|
|
GetDockingPaneManager()->RecalcFrameLayout(this, TRUE);
|
|
|
|
SelectPane(pPane, bSetFocus);
|
|
|
|
SAFE_CALLPTR(m_pParentContainer, OnChildContainerChanged(this));
|
|
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::RemovePane(CXTPDockingPaneBase* pPane)
|
|
{
|
|
ASSERT(pPane->GetContainer() == this);
|
|
|
|
POSITION pos = m_lstPanes.Find((CXTPDockingPane*)pPane);
|
|
ASSERT(pos);
|
|
|
|
m_lstPanes.RemoveAt(pos);
|
|
OnTabsChanged();
|
|
|
|
pPane->SetParentContainer(NULL);
|
|
|
|
m_pParentContainer->OnChildContainerChanged(this);
|
|
|
|
if (m_lstPanes.IsEmpty())
|
|
{
|
|
if (m_bActive)
|
|
{
|
|
GetDockingPaneManager()->GetSite()->SetFocus();
|
|
m_bActive = FALSE;
|
|
GetDockingPaneManager()->OnActivatePane(FALSE, m_pSelectedPane);
|
|
}
|
|
DestroyWindow();
|
|
}
|
|
|
|
m_bDelayRedraw = TRUE;
|
|
GetDockingPaneManager()->RecalcFrameLayout(this, TRUE);
|
|
|
|
if (pPane == m_pSelectedPane)
|
|
{
|
|
SelectPane((CXTPDockingPane*)GetLastPane());
|
|
}
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPDockingPaneTabbedContainer, CWnd)
|
|
ON_WM_PAINT()
|
|
ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_RBUTTONUP()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_CAPTURECHANGED()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
|
|
ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
|
|
ON_WM_DESTROY()
|
|
ON_WM_SETCURSOR()
|
|
ON_WM_KEYDOWN()
|
|
ON_MESSAGE(WM_GETOBJECT, OnGetObject)
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
// CXTPDockingPaneTabbedContainer message handlers
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnDestroy()
|
|
{
|
|
CWnd::OnDestroy();
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::DeletePane()
|
|
{
|
|
InternalRelease();
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnFinalRelease()
|
|
{
|
|
if (m_hWnd != NULL)
|
|
DestroyWindow();
|
|
|
|
CCmdTarget::OnFinalRelease();
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
{
|
|
if (GetDockingPaneManager()->m_bShowSizeCursorWhileDragging)
|
|
{
|
|
POINT pt;
|
|
GetCursorPos(&pt);
|
|
ScreenToClient(&pt);
|
|
|
|
if (CXTPDockingPaneBase::GetPaintManager()->GetCaptionGripperRect(this).PtInRect(pt))
|
|
{
|
|
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
return CWnd::OnSetCursor(pWnd, nHitTest, message);
|
|
}
|
|
|
|
|
|
LRESULT CXTPDockingPaneTabbedContainer::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
|
|
{
|
|
CDC* pDC = CDC::FromHandle((HDC)wParam);
|
|
if (pDC)
|
|
{
|
|
CXTPClientRect rc(this);
|
|
CXTPDockingPaneBase::GetPaintManager()->DrawPane(pDC, this, rc);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnPaint()
|
|
{
|
|
CPaintDC dcPaint(this);
|
|
CXTPClientRect rc(this);
|
|
CXTPBufferDC dc(dcPaint);
|
|
|
|
CXTPDockingPaneBase::GetPaintManager()->DrawPane(&dc, this, rc);
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneTabbedContainer::ShowTitle(BOOL bShow)
|
|
{
|
|
if (m_bTitleVisible != bShow)
|
|
{
|
|
m_bTitleVisible = bShow;
|
|
|
|
m_bDelayRedraw = TRUE;
|
|
GetDockingPaneManager()->RecalcFrameLayout(this, TRUE);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsTitleVisible() const
|
|
{
|
|
return m_bTitleVisible &&
|
|
(m_pSelectedPane && ((m_pSelectedPane->GetOptions() & xtpPaneNoCaption) == 0)) &&
|
|
CXTPDockingPaneBase::GetPaintManager()->m_bShowCaption;
|
|
}
|
|
|
|
|
|
CString CXTPDockingPaneTabbedContainer::GetTitle() const
|
|
{
|
|
return m_pSelectedPane ? m_pSelectedPane->GetTitle() : _T("");
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnFocusChanged()
|
|
{
|
|
if (!GetSafeHwnd() || IsEmpty())
|
|
return;
|
|
|
|
CWnd* pFocus = GetFocus();
|
|
BOOL bActive = (pFocus->GetSafeHwnd() && (pFocus == this || IsChild(pFocus) ||
|
|
(pFocus->GetOwner()->GetSafeHwnd() && IsChild(pFocus->GetOwner()))));
|
|
|
|
if (bActive != m_bActive)
|
|
{
|
|
m_bActive = bActive;
|
|
|
|
GetDockingPaneManager()->OnActivatePane(bActive, m_pSelectedPane);
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
else if (m_bActive && GetDockingPaneManager()->GetActivePane() != m_pSelectedPane)
|
|
{
|
|
GetDockingPaneManager()->OnActivatePane(bActive, m_pSelectedPane);
|
|
}
|
|
}
|
|
|
|
#define DOCKINGPANE_HITCAPTION -2
|
|
|
|
int CXTPDockingPaneTabbedContainer::HitTest(CPoint point) const
|
|
{
|
|
CXTPClientRect rc(this);
|
|
|
|
if (IsTitleVisible())
|
|
{
|
|
if (rc.PtInRect(point))
|
|
{
|
|
CXTPDockingPaneBase::GetPaintManager()->AdjustCaptionRect(this, rc);
|
|
if (!rc.PtInRect(point))
|
|
{
|
|
return DOCKINGPANE_HITCAPTION;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsTabsVisible())
|
|
{
|
|
CXTPTabManagerItem* pItem = CXTPTabManager::HitTest(point);
|
|
return pItem ? pItem->GetIndex() : -1;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
CXTPTabManagerItem* CXTPDockingPaneTabbedContainer::GetPaneTab(CXTPDockingPane* pPane) const
|
|
{
|
|
for (int i = 0; i < GetItemCount(); i++)
|
|
{
|
|
if (GetItemPane(i) == pPane)
|
|
return GetItem(i);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::SelectPane(CXTPDockingPane* pPane, BOOL bSetFocus, BOOL bDelayRedraw)
|
|
{
|
|
if (m_pSelectedPane != pPane)
|
|
{
|
|
m_pSelectedPane = pPane;
|
|
|
|
if (bDelayRedraw)
|
|
{
|
|
m_bEnsureSelectedTab = TRUE;
|
|
m_bDelayRedraw = TRUE;
|
|
|
|
GetDockingPaneManager()->RecalcFrameLayout(this, TRUE);
|
|
SAFE_CALLPTR(m_pParentContainer, OnChildContainerChanged(this));
|
|
}
|
|
else
|
|
{
|
|
InvalidatePane(TRUE);
|
|
EnsureSelectedTabVisible();
|
|
}
|
|
|
|
if (m_hWnd && m_pSelectedPane)
|
|
{
|
|
SetWindowText(GetTitle());
|
|
}
|
|
}
|
|
|
|
if (bSetFocus)
|
|
{
|
|
if (m_bActive) GetDockingPaneManager()->OnActivatePane(TRUE, m_pSelectedPane);
|
|
SAFE_CALLPTR(pPane, SetFocus());
|
|
}
|
|
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnRButtonUp(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
XTP_DOCKINGPANE_CLICK menu;
|
|
menu.pContainer = this;
|
|
menu.pPane = GetItemPane(HitTest(point));
|
|
if (!menu.pPane) menu.pPane = m_pSelectedPane;
|
|
ClientToScreen(&point);
|
|
menu.pt = point;
|
|
menu.rcExclude.SetRectEmpty();
|
|
|
|
if (GetDockingPaneManager()->NotifyOwner(XTP_DPN_CONTEXTMENU, (LPARAM)&menu))
|
|
return;
|
|
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnRButtonDown(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
int nHit = HitTest(point);
|
|
if (nHit >= 0)
|
|
{
|
|
SelectPane(GetItemPane(nHit));
|
|
GetDockingPaneManager()->RecalcFrameLayout(this);
|
|
}
|
|
|
|
if (m_pSelectedPane)
|
|
m_pSelectedPane->SetFocus();
|
|
else
|
|
SetFocus();
|
|
|
|
GetDockingPaneManager()->UpdatePanes();
|
|
|
|
GetDockingPaneManager()->NotifyOwner(XTP_DPN_RCLICK, (LPARAM)(CXTPDockingPaneBase*)this);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnCaptionLButtonDown(CPoint point)
|
|
{
|
|
_RestoreFocus();
|
|
|
|
if (GetKeyState(VK_LBUTTON) < 0)
|
|
{
|
|
if (GetDockingPaneManager()->NotifyAction(xtpPaneActionDragging, m_pSelectedPane))
|
|
return;
|
|
|
|
CXTPDockingPaneContext* pContext = GetDockingPaneManager()->GetDockingContext();
|
|
pContext->Drag(this, point);
|
|
}
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneTabbedContainer::NormalizeDockingSize()
|
|
{
|
|
XTPDockingPaneDirection direction = GetDockingPaneManager()->GetPaneDirection(this);
|
|
BOOL bHoriz = (direction == xtpPaneDockLeft) || (direction == xtpPaneDockRight);
|
|
|
|
if (bHoriz) m_szDocking.cx = m_rcWindow.Width();
|
|
else m_szDocking.cy = m_rcWindow.Height();
|
|
|
|
POSITION pos = GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = GetNext(pos);
|
|
if (!pPane->IsEmpty())
|
|
{
|
|
if (bHoriz) pPane->m_szDocking.cx = m_szDocking.cx;
|
|
else pPane->m_szDocking.cy = m_szDocking.cy;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::ClosePane(CXTPDockingPane* pPane)
|
|
{
|
|
if (!pPane)
|
|
return;
|
|
|
|
if ((pPane->GetOptions() & xtpPaneNoCloseable) != 0)
|
|
return;
|
|
|
|
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
|
|
|
|
pPane->InternalAddRef();
|
|
if (!pManager->NotifyAction(xtpPaneActionClosing, pPane))
|
|
{
|
|
pPane->Close();
|
|
pManager->NotifyAction(xtpPaneActionClosed, pPane);
|
|
}
|
|
pPane->InternalRelease();
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnNavigateButtonClick(CXTPTabManagerNavigateButton* pButton)
|
|
{
|
|
CXTPTabManager::OnNavigateButtonClick(pButton->GetID());
|
|
|
|
CXTPTabManagerItem* pItem = pButton->GetItem() ? pButton->GetItem() : m_pSelected;
|
|
|
|
if (pItem && (pButton->GetID() == xtpTabNavigateButtonClose) && pItem->IsClosable())
|
|
{
|
|
CXTPDockingPane* pSelectedPane = (CXTPDockingPane*)pItem->GetData();
|
|
|
|
ClosePane(pSelectedPane);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnCaptionButtonClick(CXTPDockingPaneCaptionButton* pButton)
|
|
{
|
|
CXTPDockingPane* pSelectedPane = m_pSelectedPane;
|
|
|
|
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
|
|
|
|
switch (pButton->GetID())
|
|
{
|
|
case XTP_IDS_DOCKINGPANE_CLOSE:
|
|
|
|
if (pManager->m_bCloseGroupOnButtonClick)
|
|
{
|
|
POSITION pos = m_lstPanes.GetTailPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)m_lstPanes.GetPrev(pos);
|
|
|
|
ClosePane(pPane);
|
|
}
|
|
|
|
}
|
|
else if (pSelectedPane)
|
|
{
|
|
ClosePane(pSelectedPane);
|
|
}
|
|
break;
|
|
|
|
|
|
case XTP_IDS_DOCKINGPANE_AUTOHIDE:
|
|
|
|
if (!IsHidden())
|
|
{
|
|
if (!pManager->NotifyAction(xtpPaneActionUnpinning, pSelectedPane))
|
|
{
|
|
GetDockingSite()->SetFocus();
|
|
NormalizeDockingSize();
|
|
pSelectedPane->Hide();
|
|
pManager->NotifyAction(xtpPaneActionUnpinned, pSelectedPane);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
GetDockingPaneManager()->ToggleDocking(pManager->m_bHideGroupOnButtonClick ?
|
|
(CXTPDockingPaneBase*)this : (CXTPDockingPaneBase*)pSelectedPane);
|
|
}
|
|
|
|
break;
|
|
|
|
case XTP_IDS_DOCKINGPANE_MAXIMIZE:
|
|
Maximize();
|
|
break;
|
|
|
|
case XTP_IDS_DOCKINGPANE_RESTORE:
|
|
Restore();
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::OnCaptionButtonDown(CXTPDockingPaneCaptionButton* pButton)
|
|
{
|
|
switch (pButton->GetID())
|
|
{
|
|
case XTP_IDS_DOCKINGPANE_MENU:
|
|
if (m_pSelectedPane)
|
|
{
|
|
InternalAddRef();
|
|
|
|
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
|
|
XTP_DOCKINGPANE_CLICK menu;
|
|
|
|
menu.pContainer = this;
|
|
menu.rcExclude = pButton->GetRect();
|
|
ClientToScreen(&menu.rcExclude);
|
|
|
|
menu.pt = GetExStyle() & WS_EX_LAYOUTRTL ? CPoint(menu.rcExclude.right, menu.rcExclude.bottom) : CPoint(menu.rcExclude.left, menu.rcExclude.bottom);
|
|
menu.pPane = m_pSelectedPane;
|
|
pButton->m_bPressed = TRUE;
|
|
Invalidate(FALSE);
|
|
|
|
pManager->NotifyOwner(XTP_DPN_CONTEXTMENU, (LPARAM)&menu);
|
|
|
|
pButton->m_bPressed = FALSE;
|
|
if (m_hWnd) Invalidate(FALSE);
|
|
|
|
InternalRelease();
|
|
}
|
|
return TRUE;
|
|
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneTabbedContainer::_RestoreFocus()
|
|
{
|
|
if (m_pSelectedPane)
|
|
m_pSelectedPane->SetFocus();
|
|
else
|
|
SetFocus();
|
|
|
|
GetDockingPaneManager()->UpdatePanes();
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnLButtonDown(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
CXTPDockingPaneCaptionButton* pButton = HitTestCaptionButton(point);
|
|
|
|
if (pButton)
|
|
{
|
|
_RestoreFocus();
|
|
|
|
if (m_pSelectedPane && OnCaptionButtonDown(pButton))
|
|
return;
|
|
|
|
if (pButton->Click(this, point) && m_pSelectedPane)
|
|
{
|
|
OnCaptionButtonClick(pButton);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (IsTabsVisible() && PerformClick(m_hWnd, point, TRUE))
|
|
return;
|
|
|
|
int nHit = HitTest(point);
|
|
if (nHit == DOCKINGPANE_HITCAPTION && !IsHidden())
|
|
{
|
|
ClientToScreen(&point);
|
|
OnCaptionLButtonDown(point);
|
|
}
|
|
else if (nHit >= 0)
|
|
{
|
|
CXTPDockingPane* pPane = GetItemPane(nHit);
|
|
if (GetDockingPaneManager()->NotifyAction(xtpPaneActionDragging, pPane))
|
|
{
|
|
SelectPane(pPane, TRUE, FALSE);
|
|
PerformMouseMove(m_hWnd, point);
|
|
Invalidate(FALSE);
|
|
return;
|
|
}
|
|
|
|
m_lstRects.RemoveAll();
|
|
for (int j = 0; j < GetItemCount(); j++)
|
|
{
|
|
CRect rc(GetItem(j)->GetRect());
|
|
m_lstRects.Add(rc);
|
|
}
|
|
|
|
m_pTrackingPane = pPane;
|
|
SelectPane(m_pTrackingPane, TRUE, FALSE);
|
|
|
|
PerformMouseMove(m_hWnd, point);
|
|
|
|
SetCapture();
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
else
|
|
{
|
|
_RestoreFocus();
|
|
}
|
|
}
|
|
|
|
CXTPDockingPane* CXTPDockingPaneTabbedContainer::GetItemPane(int nIndex) const
|
|
{
|
|
return nIndex >= 0 ? (CXTPDockingPane*)GetItem(nIndex)->GetData() : NULL;
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnLButtonDblClk(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
if (PerformClick(m_hWnd, point, TRUE))
|
|
return;
|
|
|
|
if (HitTestCaptionButton(point))
|
|
return;
|
|
|
|
int nHit = HitTest(point);
|
|
if (nHit == DOCKINGPANE_HITCAPTION)
|
|
{
|
|
CXTPDockingPane* pSelected = GetSelected();
|
|
|
|
if (IsHidden() && pSelected && ((pSelected->GetOptions() & xtpPaneNoHideable) != 0))
|
|
return;
|
|
|
|
if (!IsHidden() && pSelected && ((pSelected->GetOptions() & xtpPaneNoFloatableByCaptionDoubleClick) != 0))
|
|
return;
|
|
|
|
GetDockingPaneManager()->ToggleDocking(this);
|
|
}
|
|
else if (nHit >= 0)
|
|
{
|
|
CXTPDockingPane* pPane = GetItemPane(nHit);
|
|
|
|
if ((pPane->GetOptions() & xtpPaneNoFloatableByTabDoubleClick) == 0)
|
|
{
|
|
GetDockingPaneManager()->ToggleDocking(pPane);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneTabbedContainer::_Swap(CXTPDockingPane* p1, CXTPDockingPane* p2)
|
|
{
|
|
POSITION pos1 = m_lstPanes.Find(p1);
|
|
POSITION pos2 = m_lstPanes.Find(p2);
|
|
ASSERT(pos1 && pos2);
|
|
|
|
m_lstPanes.SetAt(pos1, p2);
|
|
m_lstPanes.SetAt(pos2, p1);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
PerformMouseMove(m_hWnd, point);
|
|
|
|
if (m_pTrackingPane)
|
|
{
|
|
for (int i = 0; i < m_lstRects.GetSize(); i++)
|
|
{
|
|
if (GetItemPane(i) != m_pTrackingPane && m_lstRects[i].PtInRect(point))
|
|
{
|
|
_Swap(GetItemPane(i), m_pTrackingPane);
|
|
|
|
InvalidatePane(TRUE);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if (CXTPTabManager::HitTest(point) == NULL)
|
|
{
|
|
if (GetDockingPaneManager()->NotifyAction(xtpPaneActionDetaching, m_pTrackingPane))
|
|
return;
|
|
|
|
ASSERT(m_pSelectedPane == m_pTrackingPane);
|
|
m_pTrackingPane = NULL;
|
|
ReleaseCapture();
|
|
|
|
ClientToScreen(&point);
|
|
|
|
CXTPDockingPaneContext* pContext = GetDockingPaneManager()->GetDockingContext();
|
|
pContext->Drag(m_pSelectedPane, point);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pCaptionButtons->CheckForMouseOver(point);
|
|
}
|
|
|
|
CWnd::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnMouseLeave()
|
|
{
|
|
OnMouseMove(0, CPoint(-1, -1));
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
if (m_pTrackingPane)
|
|
{
|
|
m_pTrackingPane = NULL;
|
|
if (GetCapture() == this) ReleaseCapture();
|
|
}
|
|
|
|
CWnd::OnLButtonUp(nFlags, point);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnCaptureChanged(CWnd* pWnd)
|
|
{
|
|
m_pTrackingPane = NULL;
|
|
CWnd::OnCaptureChanged(pWnd);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnParentContainerChanged(CXTPDockingPaneBase* pContainer)
|
|
{
|
|
m_pDockingSite = pContainer->m_pDockingSite;
|
|
m_bTitleVisible = TRUE;
|
|
if (pContainer->GetType() == xtpPaneTypeAutoHidePanel)
|
|
{
|
|
if (m_hWnd) ShowWindow(SW_HIDE); //?
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::CanAttach(CRect& rcClient, CPoint pt) const
|
|
{
|
|
CRect rcTitle(rcClient);
|
|
BOOL bVertical = IsCaptionVertical();
|
|
|
|
if (m_bTitleVisible)
|
|
{
|
|
if (bVertical)
|
|
{
|
|
rcClient.left += CXTPDockingPaneBase::GetPaintManager()->GetCaptionHeight() + 3;
|
|
}
|
|
else
|
|
{
|
|
rcClient.top += CXTPDockingPaneBase::GetPaintManager()->GetCaptionHeight() + 3;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SAFE_CALLPTR(m_pDockingSite, GetWindowRect(rcTitle));
|
|
}
|
|
|
|
if (bVertical)
|
|
{
|
|
rcTitle.right = rcClient.left;
|
|
}
|
|
else
|
|
{
|
|
rcTitle.bottom = rcClient.top;
|
|
}
|
|
|
|
if (rcTitle.PtInRect(pt))
|
|
return TRUE;
|
|
|
|
if (IsTabsVisible())
|
|
{
|
|
CRect rcTabs(rcClient);
|
|
rcClient.bottom -= CXTPDockingPaneBase::GetPaintManager()->GetTabsHeight();
|
|
rcTabs.top = rcClient.bottom;
|
|
|
|
if (rcTabs.PtInRect(pt))
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::Copy(CXTPDockingPaneBase* pCloneBase, CXTPPaneToPaneMap* pMap, DWORD dwIgnoredOptions)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pClone = (CXTPDockingPaneTabbedContainer*)pCloneBase;
|
|
ASSERT(pClone);
|
|
if (!pClone)
|
|
return;
|
|
|
|
m_bActive = FALSE;
|
|
m_pDockingSite = GetDockingPaneManager()->GetSite();
|
|
m_pSelectedPane = m_pTrackingPane = NULL;
|
|
|
|
m_rcWindow = pClone->m_rcWindow;
|
|
m_szDocking = pClone->m_szDocking;
|
|
m_bTitleVisible = TRUE;
|
|
m_nLockReposition = 0;
|
|
|
|
if (pClone->m_pLayout != m_pLayout)
|
|
{
|
|
m_bMaximized = pClone->m_bMaximized;
|
|
}
|
|
|
|
CXTPDockingPane* pSelected = NULL;
|
|
if (pMap)
|
|
{
|
|
POSITION pos = pClone->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)pClone->GetNext(pos);
|
|
CXTPDockingPane* pNewPane = (CXTPDockingPane*)pPane->Clone(m_pLayout, pMap);
|
|
if (pClone->GetSelected() == pPane) pSelected = pNewPane;
|
|
_InsertPane(pNewPane);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
POSITION pos = pClone->m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)pClone->GetNext(pos);
|
|
|
|
ASSERT(pPane->GetType() == xtpPaneTypeDockingPane);
|
|
|
|
if ((((CXTPDockingPane*)pPane)->GetOptions() & dwIgnoredOptions) == 0)
|
|
{
|
|
if (pClone->GetSelected() == pPane && pSelected == NULL) pSelected = pPane;
|
|
|
|
pPane->m_pParentContainer->RemovePane(pPane);
|
|
_InsertPane(pPane);
|
|
}
|
|
}
|
|
}
|
|
if (pSelected) SelectPane(pSelected, FALSE);
|
|
|
|
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsHidden() const
|
|
{
|
|
return GetContainer() && GetContainer()->GetType() == xtpPaneTypeAutoHidePanel;
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::Show(BOOL bSetFocus)
|
|
{
|
|
if (m_pSelectedPane &&m_pParentContainer &&
|
|
m_pParentContainer->GetType() == xtpPaneTypeAutoHidePanel)
|
|
{
|
|
((CXTPDockingPaneAutoHidePanel*)m_pParentContainer)->ShowPane(m_pSelectedPane, bSetFocus);
|
|
}
|
|
else if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, GetParentFrame()))
|
|
{
|
|
((CXTPDockingPaneMiniWnd*)GetParentFrame())->Expand();
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::ShowPane(CXTPDockingPane* pPane, BOOL bSetFocus)
|
|
{
|
|
ASSERT(pPane);
|
|
|
|
if (m_pParentContainer && m_pParentContainer->GetType() == xtpPaneTypeAutoHidePanel)
|
|
{
|
|
((CXTPDockingPaneAutoHidePanel*)m_pParentContainer)->ShowPane(pPane, bSetFocus);
|
|
}
|
|
else
|
|
{
|
|
SelectPane(pPane, bSetFocus);
|
|
|
|
if (DYNAMIC_DOWNCAST(CXTPDockingPaneMiniWnd, GetParentFrame()))
|
|
((CXTPDockingPaneMiniWnd*)GetParentFrame())->Expand();
|
|
|
|
if (m_pParentContainer && m_pParentContainer->GetType() == xtpPaneTypeSidePanel)
|
|
{
|
|
((CXTPDockingPaneSidePanel*)m_pParentContainer)->Expand();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsAllowMaximize() const
|
|
{
|
|
if (!m_pParentContainer || m_pParentContainer->GetType() != xtpPaneTypeSplitterContainer)
|
|
return FALSE;
|
|
|
|
if (!GetDockingPaneManager()->IsCaptionMaximizeButtonsVisible())
|
|
return FALSE;
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
((CXTPDockingPaneSplitterContainer*)m_pParentContainer)->FindChildPane(xtpPaneTypeTabbedContainer, &lst);
|
|
|
|
if (lst.GetCount() < 2)
|
|
return FALSE;
|
|
|
|
lst.RemoveAll();
|
|
((CXTPDockingPaneSplitterContainer*)m_pParentContainer)->FindChildPane(xtpPaneTypeClient, &lst);
|
|
|
|
if (!lst.IsEmpty())
|
|
return FALSE;
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::Maximize()
|
|
{
|
|
if (!m_pDockingSite || !m_pParentContainer)
|
|
return;
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
((CXTPDockingPaneSplitterContainer*)m_pParentContainer)->FindChildPane(xtpPaneTypeTabbedContainer, &lst);
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pTabbedContainer = (CXTPDockingPaneTabbedContainer*)lst.GetNext(pos);
|
|
pTabbedContainer->m_bMaximized = pTabbedContainer == this;
|
|
}
|
|
|
|
GetDockingPaneManager()->RecalcFrameLayout(this);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::Restore()
|
|
{
|
|
if (!m_pDockingSite || !m_pParentContainer)
|
|
return;
|
|
|
|
m_bMaximized = FALSE;
|
|
GetDockingPaneManager()->RecalcFrameLayout(this);
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsPaneMaximized() const
|
|
{
|
|
if (!IsAllowMaximize())
|
|
return FALSE;
|
|
|
|
return m_bMaximized;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsPaneRestored() const
|
|
{
|
|
if (!IsAllowMaximize())
|
|
return FALSE;
|
|
|
|
return !m_bMaximized;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsPaneMinimized() const
|
|
{
|
|
if (m_bMaximized)
|
|
return FALSE;
|
|
|
|
if (!m_pParentContainer || m_pParentContainer->GetType() != xtpPaneTypeSplitterContainer)
|
|
return FALSE;
|
|
|
|
if (!GetDockingPaneManager()->IsCaptionMaximizeButtonsVisible())
|
|
return FALSE;
|
|
|
|
CXTPDockingPaneBaseList lst;
|
|
((CXTPDockingPaneSplitterContainer*)m_pParentContainer)->FindChildPane(xtpPaneTypeTabbedContainer, &lst);
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pTabbedContainer = (CXTPDockingPaneTabbedContainer*)lst.GetNext(pos);
|
|
if (pTabbedContainer->m_bMaximized)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsCaptionButtonVisible(CXTPDockingPaneCaptionButton* pButton)
|
|
{
|
|
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_CLOSE)
|
|
return m_pSelectedPane && ((m_pSelectedPane->GetOptions() & xtpPaneNoCloseable) == 0);
|
|
|
|
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_AUTOHIDE)
|
|
return m_pSelectedPane && ((m_pSelectedPane->GetOptions() & xtpPaneNoHideable) == 0) && (pButton->GetState() & xtpPanePinVisible);
|
|
|
|
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_MAXIMIZE)
|
|
return IsPaneRestored();
|
|
|
|
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_RESTORE)
|
|
return IsPaneMaximized();
|
|
|
|
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_MENU)
|
|
return m_pSelectedPane && (m_pSelectedPane->GetOptions() & xtpPaneHasMenuButton);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
LRESULT CXTPDockingPaneTabbedContainer::OnHelpHitTest(WPARAM, LPARAM lParam)
|
|
{
|
|
CXTPDockingPane* pPane = GetSelected();
|
|
CPoint point((DWORD)lParam);
|
|
|
|
int nHit = HitTest(point);
|
|
|
|
if (nHit >= 0)
|
|
{
|
|
pPane = GetItemPane(nHit);
|
|
}
|
|
|
|
if (!pPane)
|
|
return 0;
|
|
|
|
int nIDHelp = pPane->m_nIDHelp;
|
|
|
|
if (nIDHelp == 0)
|
|
{
|
|
pPane->m_hwndChild ? (int)::GetDlgCtrlID(pPane->m_hwndChild): 0;
|
|
}
|
|
|
|
if (nIDHelp == 0)
|
|
{
|
|
nIDHelp = pPane->GetID();
|
|
}
|
|
|
|
return HID_BASE_RESOURCE + nIDHelp;
|
|
}
|
|
|
|
CXTPDockingPaneCaptionButton* CXTPDockingPaneTabbedContainer::HitTestCaptionButton(CPoint point) const
|
|
{
|
|
if (IsTitleVisible())
|
|
{
|
|
for (int i = 0; i < m_pCaptionButtons->GetSize(); i++)
|
|
{
|
|
CXTPDockingPaneCaptionButton* pButton = m_pCaptionButtons->GetAt(i);
|
|
if (pButton->PtInRect(point))
|
|
return pButton->IsEnabled() ? pButton : NULL;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
INT_PTR CXTPDockingPaneTabbedContainer::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
|
|
{
|
|
|
|
ASSERT_VALID(this);
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
|
|
// check child windows first by calling CControlBar
|
|
INT_PTR nHit = CWnd::OnToolHitTest(point, pTI);
|
|
if (nHit != -1)
|
|
return nHit;
|
|
|
|
CXTPDockingPaneCaptionButton* pButton = HitTestCaptionButton(point);
|
|
|
|
if (pButton)
|
|
{
|
|
nHit = (INT_PTR)pButton->GetID();
|
|
CString strTip;
|
|
XTPResourceManager()->LoadString(&strTip, (UINT)nHit);
|
|
|
|
if (strTip.GetLength() == 0)
|
|
return -1;
|
|
|
|
CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, pButton->GetRect(), nHit, strTip);
|
|
|
|
return nHit;
|
|
}
|
|
|
|
nHit = HitTest(point);
|
|
if (nHit == DOCKINGPANE_HITCAPTION)
|
|
{
|
|
CString strTip = GetSelected()->GetTitleToolTip();
|
|
|
|
if (strTip.IsEmpty())
|
|
return -1;
|
|
|
|
nHit = 2;
|
|
|
|
CRect rcCaption;
|
|
CXTPDockingPaneBase::GetPaintManager()->GetCaptionRect(this, rcCaption);
|
|
|
|
CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, rcCaption, nHit, strTip);
|
|
|
|
return nHit;
|
|
}
|
|
|
|
return PerformToolHitTest(m_hWnd, point, pTI);
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::AdjustMinMaxInfoClientRect(LPMINMAXINFO pMinMaxInfo, BOOL bCaptionOnly) const
|
|
{
|
|
CRect rc(0, 0, 1000, 1000);
|
|
if (bCaptionOnly)
|
|
{
|
|
CXTPDockingPaneBase::GetPaintManager()->AdjustCaptionRect(this, rc);
|
|
}
|
|
else
|
|
{
|
|
CXTPDockingPaneBase::GetPaintManager()->AdjustClientRect((CXTPDockingPaneTabbedContainer*)this, rc, FALSE);
|
|
}
|
|
|
|
pMinMaxInfo->ptMinTrackSize.x += 1000 - rc.Width();
|
|
pMinMaxInfo->ptMinTrackSize.y += 1000 - rc.Height();
|
|
|
|
pMinMaxInfo->ptMaxTrackSize.x += 1000 - rc.Width();
|
|
pMinMaxInfo->ptMaxTrackSize.y += 1000 - rc.Height();
|
|
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
|
|
{
|
|
CXTPDockingPaneBase::GetMinMaxInfo(pMinMaxInfo);
|
|
|
|
if (IsEmpty())
|
|
return;
|
|
|
|
if (IsPaneMinimized())
|
|
{
|
|
if (((CXTPDockingPaneSplitterContainer*)m_pParentContainer)->IsHoriz())
|
|
pMinMaxInfo->ptMaxTrackSize.x = 0;
|
|
else
|
|
pMinMaxInfo->ptMaxTrackSize.y = 0;
|
|
|
|
AdjustMinMaxInfoClientRect(pMinMaxInfo, FALSE);
|
|
}
|
|
else
|
|
{
|
|
POSITION pos = GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = GetNext(pos);
|
|
|
|
MINMAXINFO info;
|
|
pPane->GetMinMaxInfo(&info);
|
|
|
|
pMinMaxInfo->ptMinTrackSize.x = max(pMinMaxInfo->ptMinTrackSize.x, info.ptMinTrackSize.x);
|
|
pMinMaxInfo->ptMinTrackSize.y = max(pMinMaxInfo->ptMinTrackSize.y, info.ptMinTrackSize.y);
|
|
|
|
pMinMaxInfo->ptMaxTrackSize.x = min(pMinMaxInfo->ptMaxTrackSize.x, info.ptMaxTrackSize.x);
|
|
pMinMaxInfo->ptMaxTrackSize.y = min(pMinMaxInfo->ptMaxTrackSize.y, info.ptMaxTrackSize.y);
|
|
}
|
|
AdjustMinMaxInfoClientRect(pMinMaxInfo);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneTabbedContainer::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
|
{
|
|
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
|
|
|
|
if (pManager)
|
|
{
|
|
pManager->GetToolTipContext()->FilterToolTipMessage(this, message, wParam, lParam);
|
|
}
|
|
|
|
return CWnd::OnWndMsg(message, wParam, lParam, pResult);
|
|
}
|
|
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::IsCaptionVertical() const
|
|
{
|
|
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
|
|
|
|
switch (pManager->GetCaptionDirection())
|
|
{
|
|
case xtpPaneCaptionHorizontal:
|
|
return FALSE;
|
|
|
|
case xtpPaneCaptionAutoBySize:
|
|
return m_rcWindow.Width() > m_rcWindow.Height();
|
|
|
|
case xtpPaneCaptionAutoByPosition:
|
|
XTPDockingPaneDirection direction = pManager->GetPaneDirection(this);
|
|
return (direction == xtpPaneDockTop) || (direction == xtpPaneDockBottom);
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Accessible
|
|
|
|
CCmdTarget* CXTPDockingPaneTabbedContainer::GetAccessible()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::GetAccessibleParent(IDispatch* FAR* ppdispParent)
|
|
{
|
|
*ppdispParent = NULL;
|
|
|
|
if (GetSafeHwnd())
|
|
{
|
|
return AccessibleObjectFromWindow(GetSafeHwnd(), OBJID_WINDOW, IID_IDispatch, (void**)ppdispParent);
|
|
}
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::GetAccessibleChildCount(long FAR* pChildCount)
|
|
{
|
|
if (pChildCount == 0)
|
|
return E_INVALIDARG;
|
|
|
|
*pChildCount = GetItemCount() + 1 + (int)m_pCaptionButtons->GetSize();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::GetAccessibleChild(VARIANT varChild, IDispatch* FAR* ppdispChild)
|
|
{
|
|
*ppdispChild = NULL;
|
|
int nChild = GetChildIndex(&varChild) - 1;
|
|
|
|
if (nChild == 0 && GetSelected())
|
|
return AccessibleObjectFromWindow(GetSelected()->m_hwndChild, OBJID_WINDOW, IID_IDispatch, (void**)ppdispChild);
|
|
|
|
nChild--;
|
|
|
|
if (nChild >= 0 && nChild < GetItemCount())
|
|
{
|
|
CXTPDockingPane* pPane = GetItemPane(nChild);
|
|
if (pPane)
|
|
{
|
|
*ppdispChild = pPane->GetIDispatch(TRUE);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
nChild -= GetItemCount();
|
|
|
|
if (nChild >= 0 && nChild < m_pCaptionButtons->GetSize())
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::GetAccessibleName(VARIANT varChild, BSTR* pszName)
|
|
{
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
if (nChild == CHILDID_SELF || nChild == -1)
|
|
{
|
|
*pszName = GetTitle().AllocSysString();
|
|
return S_OK;
|
|
}
|
|
|
|
nChild -= 1 + GetItemCount() + 1;
|
|
|
|
if (nChild >= 0 && nChild < m_pCaptionButtons->GetSize())
|
|
{
|
|
int nId = m_pCaptionButtons->GetAt(nChild)->GetID();
|
|
CString strTip;
|
|
XTPResourceManager()->LoadString(&strTip, nId);
|
|
|
|
*pszName = strTip.AllocSysString();
|
|
return S_OK;
|
|
}
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::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_PAGETABLIST;
|
|
return S_OK;
|
|
}
|
|
|
|
nChild -= 1 + GetItemCount() + 1;
|
|
|
|
if (nChild >= 0 && nChild < m_pCaptionButtons->GetSize())
|
|
{
|
|
pvarRole->vt = VT_I4;
|
|
pvarRole->lVal = ROLE_SYSTEM_PUSHBUTTON;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::GetAccessibleState(VARIANT varChild, VARIANT* pvarState)
|
|
{
|
|
pvarState->vt = VT_I4;
|
|
pvarState->lVal = 0;
|
|
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
nChild -= 1 + GetItemCount() + 1;
|
|
|
|
if (nChild >= 0 && nChild < m_pCaptionButtons->GetSize())
|
|
{
|
|
if (!IsTitleVisible() || !IsCaptionButtonVisible(m_pCaptionButtons->GetAt(nChild)))
|
|
pvarState->lVal |= STATE_SYSTEM_INVISIBLE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::AccessibleLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild)
|
|
{
|
|
*pxLeft = *pyTop = *pcxWidth = *pcyHeight = 0;
|
|
|
|
if (!GetSafeHwnd())
|
|
return S_OK;
|
|
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
if (nChild == CHILDID_SELF)
|
|
{
|
|
CRect rc;
|
|
GetWindowRect(&rc);
|
|
|
|
*pxLeft = rc.left;
|
|
*pyTop = rc.top;
|
|
*pcxWidth = rc.Width();
|
|
*pcyHeight = rc.Height();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
nChild -= 1 + GetItemCount() + 1;
|
|
|
|
if (nChild >= 0 && nChild < m_pCaptionButtons->GetSize())
|
|
{
|
|
CXTPDockingPaneCaptionButton* pButton = m_pCaptionButtons->GetAt(nChild);
|
|
if (!IsTitleVisible() || !IsCaptionButtonVisible(pButton))
|
|
return S_FALSE;
|
|
|
|
CRect rc;
|
|
GetWindowRect(&rc);
|
|
rc.OffsetRect(pButton->GetRect().TopLeft());
|
|
|
|
*pxLeft = rc.left;
|
|
*pyTop = rc.top;
|
|
*pcxWidth = pButton->GetRect().Width();
|
|
*pcyHeight = pButton->GetRect().Height();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::AccessibleHitTest(long xLeft, long yTop, VARIANT* pvarID)
|
|
{
|
|
if (pvarID == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
pvarID->vt = VT_EMPTY;
|
|
|
|
if (!GetSafeHwnd())
|
|
return S_FALSE;
|
|
|
|
if (!CXTPWindowRect(this).PtInRect(CPoint(xLeft, yTop)))
|
|
return S_FALSE;
|
|
|
|
CPoint pt(xLeft, yTop);
|
|
ScreenToClient(&pt);
|
|
|
|
CXTPDockingPaneCaptionButton* pButton = HitTestCaptionButton(pt);
|
|
|
|
if (pButton)
|
|
{
|
|
int nIndex = 0;
|
|
for (; nIndex < m_pCaptionButtons->GetSize(); nIndex++)
|
|
if (m_pCaptionButtons->GetAt(nIndex) == pButton)
|
|
break;
|
|
|
|
pvarID->vt = VT_I4;
|
|
pvarID->lVal = 2 + GetItemCount() + nIndex;
|
|
return S_OK;
|
|
}
|
|
|
|
int nItem = HitTest(pt);
|
|
if (nItem == DOCKINGPANE_HITCAPTION)
|
|
{
|
|
pvarID->vt = VT_I4;
|
|
pvarID->lVal = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
if (nItem == -1)
|
|
{
|
|
pvarID->vt = VT_DISPATCH;
|
|
if (GetSelected())
|
|
return AccessibleObjectFromWindow(GetSelected()->m_hwndChild, OBJID_WINDOW, IID_IDispatch, (void**)&pvarID->pdispVal);
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
pvarID->vt = VT_DISPATCH;
|
|
pvarID->pdispVal = GetItemPane(nItem)->GetIDispatch(TRUE);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::GetAccessibleDefaultAction(VARIANT varChild, BSTR* pszDefaultAction)
|
|
{
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
nChild -= 1 + GetItemCount() + 1;
|
|
|
|
if (nChild >= 0 && nChild < m_pCaptionButtons->GetSize())
|
|
{
|
|
|
|
*pszDefaultAction = SysAllocString(L"Press");
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT CXTPDockingPaneTabbedContainer::AccessibleDoDefaultAction(VARIANT varChild)
|
|
{
|
|
SAFE_MANAGE_STATE(m_pModuleState);
|
|
|
|
int nChild = GetChildIndex(&varChild);
|
|
|
|
nChild -= 1 + GetItemCount() + 1;
|
|
|
|
if (nChild >= 0 && nChild < m_pCaptionButtons->GetSize())
|
|
{
|
|
OnCaptionButtonClick(m_pCaptionButtons->GetAt(nChild));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
|
|
LRESULT CXTPDockingPaneTabbedContainer::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(CXTPDockingPaneTabbedContainer, CCmdTarget)
|
|
INTERFACE_PART(CXTPDockingPaneTabbedContainer, IID_IAccessible, ExternalAccessible)
|
|
END_INTERFACE_MAP()
|