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.
1493 lines
35 KiB
C++
1493 lines
35 KiB
C++
// XTPDockingPaneAutoHidePanel.cpp : implementation of the CXTPDockingPaneAutoHidePanel 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/Resource.h"
|
|
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPResourceManager.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
|
|
#include "TabManager/XTPTabManager.h"
|
|
#include "TabManager/XTPTabPaintManager.h"
|
|
|
|
#include "XTPDockingPaneDefines.h"
|
|
#include "XTPDockingPaneBase.h"
|
|
#include "XTPDockingPaneBaseContainer.h"
|
|
#include "XTPDockingPane.h"
|
|
#include "XTPDockingPaneManager.h"
|
|
#include "XTPDockingPaneTabbedContainer.h"
|
|
#include "XTPDockingPaneAutoHidePanel.h"
|
|
#include "XTPDockingPaneLayout.h"
|
|
#include "XTPDockingPanePaintManager.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define TID_CHECKACTIVE 1
|
|
#define TID_CLOSE 4
|
|
#define TID_SLIDEIN 2
|
|
#define TID_SLIDEOUT 3
|
|
|
|
const int SPLITTER_GAP = 4;
|
|
|
|
double CXTPDockingPaneAutoHideWnd::m_dAnimationDelay = -1;
|
|
int CXTPDockingPaneAutoHideWnd::m_nAnimationInterval = 16; // smother animation
|
|
int CXTPDockingPaneAutoHideWnd::m_nAnimationDuration = 128; // fast slide completion
|
|
BOOL CXTPDockingPaneAutoHidePanel::m_bCloseActiveWindow = TRUE;
|
|
DWORD CXTPDockingPaneAutoHideWnd::m_nMouseHoverDelay = HOVER_DEFAULT;
|
|
UINT CXTPDockingPaneAutoHideWnd::m_nInactiveCollapseDelay = 100;
|
|
|
|
void CXTPDockingPaneAutoHideWnd::GetMinMaxInfo (LPMINMAXINFO pMinMaxInfo, BOOL bIncludeSplitter /*= TRUE*/) const
|
|
{
|
|
ZeroMemory(pMinMaxInfo, sizeof(MINMAXINFO));
|
|
pMinMaxInfo->ptMaxTrackSize = CPoint(32000, 32000);
|
|
|
|
if (!m_pPane || !m_pPane->m_pSelectedPane)
|
|
return;
|
|
|
|
m_pPane->m_pSelectedPane->GetMinMaxInfo(pMinMaxInfo);
|
|
m_pPane->AdjustMinMaxInfoClientRect(pMinMaxInfo, TRUE);
|
|
|
|
if (!bIncludeSplitter)
|
|
return;
|
|
|
|
if (m_direction == xtpPaneDockLeft || m_direction == xtpPaneDockRight)
|
|
{
|
|
pMinMaxInfo->ptMinTrackSize.x += SPLITTER_GAP;
|
|
pMinMaxInfo->ptMaxTrackSize.x += SPLITTER_GAP;
|
|
}
|
|
else
|
|
{
|
|
pMinMaxInfo->ptMinTrackSize.y += SPLITTER_GAP;
|
|
pMinMaxInfo->ptMaxTrackSize.y += SPLITTER_GAP;
|
|
}
|
|
}
|
|
|
|
CXTPDockingPaneAutoHideWnd::CXTPDockingPaneAutoHideWnd(CXTPDockingPaneAutoHidePanel* pPanel, CXTPDockingPaneTabbedContainer* pPane)
|
|
: m_pPanel(pPanel), m_pPane(pPane)
|
|
{
|
|
ASSERT(pPane);
|
|
if (!pPane)
|
|
return;
|
|
|
|
ASSERT(pPane->m_pSelectedPane);
|
|
if (!pPane->m_pSelectedPane)
|
|
return;
|
|
|
|
m_bTracking = FALSE;
|
|
|
|
m_direction = m_pPanel->GetDirection();
|
|
m_bHoriz = (m_direction == xtpPaneDockTop || m_direction == xtpPaneDockBottom);
|
|
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
|
|
|
|
CWnd* pSite = pManager->GetSite();
|
|
CXTPDockingPaneBase* pTopPane = pManager->GetTopPane();
|
|
|
|
CRect rcClient = pTopPane->GetPaneWindowRect();
|
|
|
|
MINMAXINFO mmInfo;
|
|
GetMinMaxInfo(&mmInfo);
|
|
|
|
CRect rcAvail, rc;
|
|
BOOL bResizable = GetAvailableRect(rcAvail, rc);
|
|
|
|
CSize szDocking(pPane->m_pSelectedPane->m_szDocking.cx + SPLITTER_GAP, pPane->m_pSelectedPane->m_szDocking.cy + SPLITTER_GAP);
|
|
|
|
switch (pManager->GetRTLDirection(m_direction))
|
|
{
|
|
case xtpPaneDockLeft:
|
|
szDocking.cx = min(szDocking.cx, rcAvail.right + SPLITTER_GAP - rcClient.left);
|
|
break;
|
|
|
|
case xtpPaneDockRight:
|
|
szDocking.cx = min(szDocking.cx, rcClient.right - rcAvail.left);
|
|
break;
|
|
|
|
case xtpPaneDockTop:
|
|
szDocking.cy = min(szDocking.cy, rcAvail.bottom + SPLITTER_GAP - rcClient.top);
|
|
break;
|
|
|
|
case xtpPaneDockBottom:
|
|
szDocking.cy = min(szDocking.cy, rcClient.bottom - rcAvail.top);
|
|
break;
|
|
}
|
|
|
|
szDocking.cx = max(mmInfo.ptMinTrackSize.x, min(mmInfo.ptMaxTrackSize.x, szDocking.cx));
|
|
szDocking.cy = max(mmInfo.ptMinTrackSize.y, min(mmInfo.ptMaxTrackSize.y, szDocking.cy));
|
|
|
|
switch (pManager->GetRTLDirection(m_direction))
|
|
{
|
|
case xtpPaneDockLeft:
|
|
rcClient.right = rcClient.left + szDocking.cx;
|
|
break;
|
|
|
|
case xtpPaneDockRight:
|
|
rcClient.left = rcClient.right - szDocking.cx;
|
|
break;
|
|
|
|
case xtpPaneDockTop:
|
|
rcClient.bottom = rcClient.top + szDocking.cy;
|
|
break;
|
|
|
|
case xtpPaneDockBottom:
|
|
rcClient.top = rcClient.bottom - szDocking.cy;
|
|
break;
|
|
}
|
|
|
|
pSite->ScreenToClient(&rcClient);
|
|
|
|
HCURSOR hCursor = !bResizable || pManager->IsSplittersLocked() ? AfxGetApp()->LoadStandardCursor(IDC_ARROW) :
|
|
XTPResourceManager()->LoadCursor(!m_bHoriz ? XTP_IDC_HSPLITBAR : XTP_IDC_VSPLITBAR);
|
|
m_rcWindow = rcClient;
|
|
|
|
CreateEx(pSite->GetExStyle() & WS_EX_LAYOUTRTL, AfxRegisterWndClass(0, hCursor), _T(""),
|
|
WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, rcClient, pSite, 0);
|
|
|
|
|
|
m_nSlideStep = 0;
|
|
m_nStepsCount = 1;
|
|
|
|
if (m_dAnimationDelay != .0 && m_nAnimationInterval != 0)
|
|
{
|
|
if (m_dAnimationDelay > 0)
|
|
{
|
|
// keep the animation delay behaviour relative to 50 ms frame interval as per original
|
|
// implementation
|
|
m_nStepsCount = int((m_bHoriz ? m_rcWindow.Width() : m_rcWindow.Height()) * m_dAnimationDelay * 50 / m_nAnimationInterval);
|
|
}
|
|
else
|
|
{
|
|
m_nStepsCount = m_nAnimationDuration/m_nAnimationInterval;
|
|
}
|
|
}
|
|
if (m_nStepsCount < 1) m_nStepsCount = 1;
|
|
|
|
|
|
m_bSlideOut = FALSE;
|
|
if (m_nStepsCount > 1)
|
|
SetTimer(TID_SLIDEIN, m_nAnimationInterval, NULL);
|
|
DoSlideStep();
|
|
m_pPane->ShowWindow(SW_SHOW);
|
|
|
|
SetTimer(TID_CHECKACTIVE, m_nInactiveCollapseDelay, NULL);
|
|
|
|
m_nDeactivationCount = 6;
|
|
|
|
}
|
|
|
|
CXTPDockingPaneManager* CXTPDockingPaneAutoHideWnd::GetDockingPaneManager() const
|
|
{
|
|
ASSERT(m_pPanel);
|
|
return m_pPanel ? m_pPanel->GetDockingPaneManager() : NULL;
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneAutoHideWnd::DoSlideStep()
|
|
{
|
|
CRect rc(m_rcWindow);
|
|
|
|
switch (m_direction)
|
|
{
|
|
case xtpPaneDockLeft:
|
|
rc.right = rc.left + (m_nSlideStep + 1) * m_rcWindow.Width() / m_nStepsCount;
|
|
break;
|
|
|
|
case xtpPaneDockRight:
|
|
rc.left = rc.right - (m_nSlideStep + 1) * m_rcWindow.Width() / m_nStepsCount;
|
|
break;
|
|
|
|
case xtpPaneDockTop:
|
|
rc.bottom = rc.top + (m_nSlideStep + 1) * m_rcWindow.Height() / m_nStepsCount;
|
|
break;
|
|
|
|
case xtpPaneDockBottom:
|
|
rc.top = rc.bottom - (m_nSlideStep + 1) * m_rcWindow.Height() / m_nStepsCount;
|
|
break;
|
|
}
|
|
SetWindowPos(&CWnd::wndTop, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHideWnd::RecalcLayout(BOOL /*bNotify*/)
|
|
{
|
|
if (!m_pPane || !m_pPane->GetSafeHwnd())
|
|
return;
|
|
|
|
AFX_SIZEPARENTPARAMS layout;
|
|
layout.bStretch = TRUE;
|
|
GetClientRect(&layout.rect);
|
|
CRect rcClient(layout.rect);
|
|
layout.hDWP = ::BeginDeferWindowPos(8); // reasonable guess
|
|
|
|
CRect rcPane(CPoint(0, 0), m_rcWindow.Size());
|
|
|
|
switch (m_direction)
|
|
{
|
|
case xtpPaneDockLeft:
|
|
rcPane.OffsetRect(- m_rcWindow.Width() + rcClient.Width(), 0);
|
|
rcPane.right -= SPLITTER_GAP;
|
|
break;
|
|
|
|
case xtpPaneDockTop:
|
|
rcPane.OffsetRect(0, - m_rcWindow.Height() + rcClient.Height());
|
|
rcPane.bottom -= SPLITTER_GAP;
|
|
break;
|
|
|
|
case xtpPaneDockRight:
|
|
rcPane.left += SPLITTER_GAP;
|
|
break;
|
|
|
|
case xtpPaneDockBottom:
|
|
rcPane.top += SPLITTER_GAP;
|
|
break;
|
|
}
|
|
|
|
m_pPane->OnSizeParent(this, rcPane, &layout);
|
|
|
|
if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP))
|
|
{
|
|
TRACE0("Warning: DeferWindowPos failed - low system resources.\n");
|
|
}
|
|
}
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPDockingPaneAutoHideWnd, CMiniFrameWnd)
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPDockingPaneAutoHideWnd, CMiniFrameWnd)
|
|
ON_WM_PAINT()
|
|
ON_WM_TIMER()
|
|
ON_WM_CLOSE()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_ERASEBKGND()
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
void CXTPDockingPaneAutoHideWnd::CloseWindow()
|
|
{
|
|
if (!IsWindow(m_hWnd))
|
|
return;
|
|
|
|
ShowWindow(SW_HIDE);
|
|
|
|
if (m_pPane && m_pPane->GetSafeHwnd() && m_pPane->GetParent() == this)
|
|
{
|
|
m_pPane->ShowWindow(SW_HIDE);
|
|
m_pPane->SetDockingSite(GetDockingPaneManager()->GetSite());
|
|
}
|
|
m_pPane = 0;
|
|
|
|
if (m_pPanel && m_pPanel->m_pActiveWnd == this)
|
|
m_pPanel->m_pActiveWnd = 0;
|
|
|
|
PostMessage(WM_CLOSE);
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHideWnd::PostNcDestroy()
|
|
{
|
|
if (m_pPanel && m_pPanel->m_pActiveWnd == this)
|
|
m_pPanel->m_pActiveWnd = 0;
|
|
|
|
if (m_dwRef <= 1)
|
|
{
|
|
delete this;
|
|
}
|
|
else
|
|
{
|
|
InternalRelease();
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHideWnd::OnTimer(UINT_PTR nIDEvent)
|
|
{
|
|
if (nIDEvent == TID_CLOSE)
|
|
{
|
|
CloseWindow();
|
|
return;
|
|
}
|
|
|
|
if (!m_pPane)
|
|
return;
|
|
|
|
if (m_pPanel && m_pPanel->m_pActiveWnd != this)
|
|
return;
|
|
|
|
if (nIDEvent == TID_CHECKACTIVE)
|
|
{
|
|
if (m_bTracking)
|
|
return;
|
|
|
|
CPoint pt;
|
|
GetCursorPos(&pt);
|
|
if (!m_pPane->IsActive() && !CXTPWindowRect(this).PtInRect(pt) && !CXTPWindowRect(m_pPanel).PtInRect(pt))
|
|
{
|
|
if (!m_bSlideOut && CXTPDrawHelpers::IsTopParentActive(m_hWnd))
|
|
{
|
|
if (--m_nDeactivationCount <= 0)
|
|
{
|
|
m_nDeactivationCount = 0;
|
|
|
|
InternalAddRef();
|
|
|
|
if (!CXTPDockingPaneAutoHidePanel::m_bCloseActiveWindow || GetDockingPaneManager()->NotifyAction(xtpPaneActionCollapsing, m_pPane->GetSelected()))
|
|
{
|
|
m_nDeactivationCount = 6;
|
|
}
|
|
else
|
|
{
|
|
m_bSlideOut = TRUE;
|
|
if (m_hWnd) SetTimer(TID_SLIDEOUT, m_nAnimationInterval, NULL);
|
|
}
|
|
|
|
InternalRelease();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_nDeactivationCount = 6;
|
|
if (m_bSlideOut)
|
|
{
|
|
m_bSlideOut = FALSE;
|
|
KillTimer(TID_SLIDEOUT);
|
|
SetTimer(TID_SLIDEIN, m_nAnimationInterval, NULL);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (nIDEvent == TID_SLIDEOUT && m_bSlideOut)
|
|
{
|
|
m_nSlideStep--;
|
|
if (m_nSlideStep > -1) DoSlideStep();
|
|
else
|
|
{
|
|
m_bSlideOut = FALSE;
|
|
KillTimer(TID_SLIDEOUT);
|
|
|
|
InternalAddRef();
|
|
|
|
GetDockingPaneManager()->NotifyAction(xtpPaneActionCollapsed, m_pPane->GetSelected());
|
|
CloseWindow();
|
|
|
|
InternalRelease();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (nIDEvent == TID_SLIDEIN && !m_bSlideOut)
|
|
{
|
|
m_nSlideStep++;
|
|
if (m_nSlideStep < m_nStepsCount) DoSlideStep();
|
|
else
|
|
{
|
|
m_nSlideStep = m_nStepsCount - 1;
|
|
KillTimer(TID_SLIDEIN);
|
|
|
|
GetDockingPaneManager()->NotifyAction(xtpPaneActionExpanded, m_pPane->GetSelected());
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneAutoHideWnd::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if (m_bSlideOut)
|
|
{
|
|
OnTimer(TID_CHECKACTIVE);
|
|
return;
|
|
}
|
|
|
|
CMiniFrameWnd::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneAutoHideWnd::OnClose()
|
|
{
|
|
CMiniFrameWnd::OnClose();
|
|
}
|
|
|
|
BOOL CXTPDockingPaneAutoHideWnd::OnEraseBkgnd(CDC* /*pDC*/)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHideWnd::OnPaint()
|
|
{
|
|
CPaintDC dc(this);
|
|
|
|
if (!m_pPane)
|
|
return;
|
|
|
|
CXTPDockingPanePaintManager* pPaintManager = m_pPane->CXTPDockingPaneBase::GetPaintManager();
|
|
|
|
CXTPClientRect rc(this);
|
|
dc.FillSolidRect(rc, pPaintManager->GetXtremeColor(XPCOLOR_3DFACE));
|
|
|
|
|
|
switch (m_direction)
|
|
{
|
|
case xtpPaneDockLeft:
|
|
dc.Draw3dRect(rc.right - 1, rc.top, 1, rc.Height(), pPaintManager->GetXtremeColor(COLOR_BTNTEXT), pPaintManager->GetXtremeColor(COLOR_BTNTEXT));
|
|
dc.Draw3dRect(rc.right - 2, rc.top, 1, rc.Height(), pPaintManager->GetXtremeColor(COLOR_3DSHADOW), pPaintManager->GetXtremeColor(COLOR_3DSHADOW));
|
|
break;
|
|
|
|
case xtpPaneDockTop:
|
|
dc.Draw3dRect(rc.left, rc.bottom - 1, rc.Width(), 1, pPaintManager->GetXtremeColor(COLOR_BTNTEXT), pPaintManager->GetXtremeColor(COLOR_BTNTEXT));
|
|
dc.Draw3dRect(rc.left, rc.bottom - 2, rc.Width(), 1, pPaintManager->GetXtremeColor(COLOR_3DSHADOW), pPaintManager->GetXtremeColor(COLOR_3DSHADOW));
|
|
break;
|
|
|
|
case xtpPaneDockRight:
|
|
dc.Draw3dRect(rc.left + 1, rc.top, 1, rc.Height(), pPaintManager->GetXtremeColor(COLOR_3DHIGHLIGHT), pPaintManager->GetXtremeColor(COLOR_3DHIGHLIGHT));
|
|
break;
|
|
|
|
case xtpPaneDockBottom:
|
|
dc.Draw3dRect(rc.left, rc.top + 1, rc.Width(), 1, pPaintManager->GetXtremeColor(COLOR_3DHIGHLIGHT), pPaintManager->GetXtremeColor(COLOR_3DHIGHLIGHT));
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHideWnd::Reposition(CRect rc, CRect rcClient)
|
|
{
|
|
CWnd* pSite = GetDockingPaneManager()->GetSite();
|
|
|
|
switch (GetDockingPaneManager()->GetRTLDirection(m_direction))
|
|
{
|
|
case xtpPaneDockLeft: rc.left = rcClient.left; break;
|
|
case xtpPaneDockRight: rc.right = rcClient.right; break;
|
|
case xtpPaneDockTop: rc.top = rcClient.top; break;
|
|
case xtpPaneDockBottom: rc.bottom = rcClient.bottom; break;
|
|
}
|
|
if (!m_bHoriz) m_pPane->m_pSelectedPane->m_szDocking.cx = rc.Width();
|
|
else m_pPane->m_pSelectedPane->m_szDocking.cy = rc.Height();
|
|
|
|
pSite->ScreenToClient(&rc);
|
|
m_rcWindow = rc;
|
|
MoveWindow(m_rcWindow);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
BOOL CXTPDockingPaneAutoHideWnd::GetAvailableRect(CRect& rcAvail, CRect& rc) const
|
|
{
|
|
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
|
|
if (!pManager)
|
|
return FALSE;
|
|
|
|
CRect rcClient = pManager->GetTopPane()->GetPaneWindowRect();
|
|
|
|
int nGap = pManager->m_nSplitterGap + SPLITTER_GAP;
|
|
|
|
rcAvail = rcClient;
|
|
|
|
MINMAXINFO mmInfo;
|
|
GetMinMaxInfo(&mmInfo, m_direction == xtpPaneDockRight || m_direction == xtpPaneDockBottom);
|
|
|
|
switch (m_direction)
|
|
{
|
|
case xtpPaneDockLeft:
|
|
rcAvail.DeflateRect(max(mmInfo.ptMinTrackSize.x, nGap), 0, nGap, 0);
|
|
|
|
if (rcAvail.right - rcClient.left > mmInfo.ptMaxTrackSize.x)
|
|
rcAvail.right = mmInfo.ptMaxTrackSize.x + rcClient.left;
|
|
|
|
if (rcAvail.left >= rcAvail.right)
|
|
return FALSE;
|
|
|
|
rc.left = rc.right - SPLITTER_GAP;
|
|
break;
|
|
|
|
case xtpPaneDockRight:
|
|
rcAvail.DeflateRect(nGap, 0, max(mmInfo.ptMinTrackSize.x, nGap), 0);
|
|
|
|
if (rcClient.right - rcAvail.left > mmInfo.ptMaxTrackSize.x)
|
|
rcAvail.left = rcClient.right - mmInfo.ptMaxTrackSize.x;
|
|
|
|
if (rcAvail.left >= rcAvail.right)
|
|
return FALSE;
|
|
|
|
rc.right = rc.left + SPLITTER_GAP;
|
|
break;
|
|
|
|
case xtpPaneDockTop:
|
|
rcAvail.DeflateRect(0, max(mmInfo.ptMinTrackSize.y, nGap), 0, nGap);
|
|
|
|
if (rcAvail.bottom - rcClient.top > mmInfo.ptMaxTrackSize.y)
|
|
rcAvail.bottom = mmInfo.ptMaxTrackSize.y + rcClient.top;
|
|
|
|
if (rcAvail.top >= rcAvail.bottom)
|
|
return FALSE;
|
|
|
|
rc.top = rc.bottom - SPLITTER_GAP;
|
|
break;
|
|
|
|
case xtpPaneDockBottom:
|
|
rcAvail.DeflateRect(0, nGap, 0, max(mmInfo.ptMinTrackSize.y, nGap));
|
|
|
|
if (rcClient.bottom - rcAvail.top > mmInfo.ptMaxTrackSize.y)
|
|
rcAvail.top = rcClient.bottom - mmInfo.ptMaxTrackSize.y;
|
|
|
|
if (rcAvail.top >= rcAvail.bottom)
|
|
return FALSE;
|
|
|
|
rc.bottom = rc.top + SPLITTER_GAP;
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHideWnd::OnLButtonDown(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
|
|
|
|
if (!pManager || pManager->IsSplittersLocked())
|
|
return;
|
|
|
|
if (!m_pPane)
|
|
return;
|
|
|
|
CXTPWindowRect rc(this);
|
|
CRect rcClient = pManager->GetTopPane()->GetPaneWindowRect();
|
|
|
|
CRect rcAvail;
|
|
if (!GetAvailableRect(rcAvail, rc))
|
|
return;
|
|
|
|
if (m_pPane->OnAction(xtpPaneActionSplitterResizing))
|
|
return;
|
|
|
|
m_bTracking = TRUE;
|
|
|
|
if (pManager->IsSplitterTrackerUsed())
|
|
{
|
|
if (GetExStyle() & WS_EX_LAYOUTRTL)
|
|
point = rc.TopLeft();
|
|
else ClientToScreen(&point);
|
|
|
|
|
|
CXTPSplitterTracker tracker;
|
|
|
|
if (tracker.Track(this, rcAvail, rc, point, !m_bHoriz))
|
|
{
|
|
Reposition(rc, rcClient);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetCapture();
|
|
|
|
while (CWnd::GetCapture() == this)
|
|
{
|
|
MSG msg;
|
|
|
|
if (!GetMessage(&msg, NULL, 0, 0))
|
|
break;
|
|
|
|
if (msg.message == WM_MOUSEMOVE)
|
|
{
|
|
point = CPoint(msg.lParam);
|
|
ClientToScreen(&point);
|
|
|
|
point.x = max(min(point.x, rcAvail.right), rcAvail.left);
|
|
point.y = max(min(point.y, rcAvail.bottom), rcAvail.top);
|
|
|
|
if (!m_bHoriz)
|
|
{
|
|
if (rc.left == point.x)
|
|
continue;
|
|
rc.OffsetRect(point.x - rc.left, 0);
|
|
}
|
|
else
|
|
{
|
|
if (rc.top == point.y)
|
|
continue;
|
|
rc.OffsetRect(0, point.y - rc.top);
|
|
}
|
|
|
|
Reposition(rc, rcClient);
|
|
}
|
|
else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) break;
|
|
else if (msg.message == WM_LBUTTONUP) break;
|
|
else ::DispatchMessage(&msg);
|
|
}
|
|
|
|
if (CWnd::GetCapture() == this) ReleaseCapture();
|
|
}
|
|
|
|
m_bTracking = FALSE;
|
|
|
|
m_pPane->OnAction(xtpPaneActionSplitterResized);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CPanelDropTarget
|
|
|
|
class CXTPDockingPaneAutoHidePanel::CPanelDropTarget : public COleDropTarget
|
|
{
|
|
public:
|
|
CPanelDropTarget()
|
|
{
|
|
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)
|
|
{
|
|
CXTPDockingPaneAutoHidePanel* pPanel = (CXTPDockingPaneAutoHidePanel*)pWnd;
|
|
ASSERT_VALID(pPanel);
|
|
|
|
if (!pPanel->GetPaintManager()->m_bSelectOnDragOver)
|
|
return DROPEFFECT_NONE;
|
|
|
|
if (m_dwDragLastTick != (DWORD)-1 && pPanel->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
|
|
{
|
|
CXTPDockingPane* pPane = pPanel->HitTest(point);
|
|
if (pPane)
|
|
{
|
|
if (!(pPanel->m_pActiveWnd && pPanel->m_pActiveWnd->GetPane()->GetSelected() == pPane))
|
|
{
|
|
pPanel->ShowPane(pPane, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_dwDragLastTick = 0;
|
|
}
|
|
}
|
|
|
|
return DROPEFFECT_NONE;
|
|
}
|
|
|
|
protected:
|
|
DWORD m_dwDragHoverMode;
|
|
DWORD m_dwDragLastTick;
|
|
CPoint m_ptDragLastPoint;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CAutoHidePanelTabManager
|
|
|
|
class CXTPDockingPaneAutoHidePanel::CAutoHidePanelTabManager : public CXTPTabManager
|
|
{
|
|
public:
|
|
CAutoHidePanelTabManager()
|
|
{
|
|
FindNavigateButton(xtpTabNavigateButtonLeft)->SetFlags(xtpTabNavigateButtonNone);
|
|
FindNavigateButton(xtpTabNavigateButtonRight)->SetFlags(xtpTabNavigateButtonNone);
|
|
}
|
|
|
|
virtual void Reposition()
|
|
{
|
|
|
|
}
|
|
virtual BOOL DrawIcon(CDC* pDC, CPoint pt, CXTPTabManagerItem* pItem, BOOL bDraw, CSize& szIcon) const
|
|
{
|
|
return GetPanel()->DrawIcon(pDC, pt, pItem, bDraw, szIcon);
|
|
}
|
|
|
|
virtual void RedrawControl(LPCRECT lpRect, BOOL /*bAnimate*/)
|
|
{
|
|
if (GetPanel()->m_hWnd) GetPanel()->InvalidateRect(lpRect, FALSE);
|
|
}
|
|
|
|
virtual CXTPTabPaintManager* GetPaintManager() const
|
|
{
|
|
return GetPanel()->GetPaintManager();
|
|
}
|
|
|
|
CXTPTabManagerItem* Add()
|
|
{
|
|
return AddItem(GetItemCount());
|
|
}
|
|
|
|
XTPTabPosition GetPosition() const
|
|
{
|
|
return GetPanel()->GetPosition();
|
|
}
|
|
|
|
void PerformMouseMove(HWND hwnd, CPoint pt)
|
|
{
|
|
CXTPTabManager::PerformMouseMove(hwnd, pt);
|
|
}
|
|
|
|
CXTPDockingPaneAutoHidePanel* GetPanel() const;
|
|
|
|
public:
|
|
CAutoHidePanelTabManagersArray* m_pArray;
|
|
CRect m_rcManager;
|
|
};
|
|
|
|
class CXTPDockingPaneAutoHidePanel::CAutoHidePanelTabManagersArray : public CArray<CAutoHidePanelTabManager*, CAutoHidePanelTabManager*>
|
|
{
|
|
public:
|
|
|
|
~CAutoHidePanelTabManagersArray()
|
|
{
|
|
FreeAll();
|
|
}
|
|
|
|
void FreeAll()
|
|
{
|
|
for (int i = 0; i < GetSize(); i++)
|
|
{
|
|
delete GetAt(i);
|
|
}
|
|
RemoveAll();
|
|
}
|
|
CAutoHidePanelTabManager* AddManager()
|
|
{
|
|
CAutoHidePanelTabManager* pManager = new CAutoHidePanelTabManager();
|
|
Add(pManager);
|
|
pManager->m_pArray = this;
|
|
return pManager;
|
|
}
|
|
|
|
void Draw(CDC* pDC)
|
|
{
|
|
CRect rcClipBox;
|
|
pDC->GetClipBox(rcClipBox);
|
|
|
|
CXTPTabPaintManager* pPaintManager = m_pAutoHidePanel->GetPaintManager();
|
|
for (int i = 0; i < GetSize(); i++)
|
|
{
|
|
CAutoHidePanelTabManager* pManager = GetAt(i);
|
|
|
|
if (CRect().IntersectRect(rcClipBox, pManager->m_rcManager))
|
|
pPaintManager->DrawTabControl(pManager, pDC, pManager->m_rcManager);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
CXTPDockingPaneAutoHidePanel* m_pAutoHidePanel;
|
|
};
|
|
|
|
|
|
|
|
CXTPDockingPaneAutoHidePanel* CXTPDockingPaneAutoHidePanel::CAutoHidePanelTabManager::GetPanel() const
|
|
{
|
|
return m_pArray->m_pAutoHidePanel;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPDockingPaneAutoHidePanel
|
|
|
|
|
|
CXTPDockingPaneAutoHidePanel::CXTPDockingPaneAutoHidePanel(CXTPDockingPaneLayout* pLayout)
|
|
: CXTPDockingPaneBaseContainer(xtpPaneTypeAutoHidePanel, pLayout)
|
|
{
|
|
m_direction = xtpPaneDockLeft;
|
|
m_pActiveWnd = 0;
|
|
m_pTabManagers = new CAutoHidePanelTabManagersArray();
|
|
m_pTabManagers->m_pAutoHidePanel = this;
|
|
|
|
m_pDropTarget = new CPanelDropTarget();
|
|
m_rcFrameRect.SetRectEmpty();
|
|
|
|
FindNavigateButton(xtpTabNavigateButtonLeft)->SetFlags(xtpTabNavigateButtonNone);
|
|
FindNavigateButton(xtpTabNavigateButtonRight)->SetFlags(xtpTabNavigateButtonNone);
|
|
|
|
|
|
}
|
|
|
|
CXTPDockingPaneAutoHidePanel::~CXTPDockingPaneAutoHidePanel()
|
|
{
|
|
if (m_pActiveWnd)
|
|
{
|
|
m_pActiveWnd->m_pPane = 0;
|
|
m_pActiveWnd->m_pPanel = 0;
|
|
CloseActiveWindow();
|
|
}
|
|
|
|
if (m_hWnd)
|
|
DestroyWindow();
|
|
|
|
delete m_pTabManagers;
|
|
delete m_pDropTarget;
|
|
}
|
|
|
|
CXTPTabPaintManager* CXTPDockingPaneAutoHidePanel::GetPaintManager() const
|
|
{
|
|
return CXTPDockingPaneBaseContainer::GetPaintManager()->GetPanelPaintManager();
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::Reposition()
|
|
{
|
|
GetDockingPaneManager()->RecalcFrameLayout(this);
|
|
}
|
|
|
|
BOOL CXTPDockingPaneAutoHidePanel::DrawIcon(CDC* pDC, CPoint pt, CXTPTabManagerItem* pItem, BOOL bDraw, CSize& szIcon) const
|
|
{
|
|
if (!pItem)
|
|
return TRUE;
|
|
|
|
if (GetPaintManager()->m_bShowIcons == FALSE)
|
|
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;
|
|
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::RedrawControl(LPCRECT lpRect, BOOL /*bAnimate*/)
|
|
{
|
|
if (m_hWnd) InvalidateRect(lpRect, FALSE);
|
|
}
|
|
|
|
int CXTPDockingPaneAutoHidePanel::GetPanelHeight() const
|
|
{
|
|
CXTPTabPaintManagerAppearanceSet* pAppearanceSet = GetPaintManager()->GetAppearanceSet();
|
|
|
|
return pAppearanceSet->GetButtonHeight(NULL) +
|
|
pAppearanceSet->m_rcHeaderMargin.bottom + pAppearanceSet->m_rcHeaderMargin.top;
|
|
}
|
|
|
|
int CXTPDockingPaneAutoHidePanel::GetItemsLength() const
|
|
{
|
|
return m_nItemsLength;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::RefreshManagersArray(CDC* pDC, CRect rcClient)
|
|
{
|
|
BOOL bVertical = m_direction == xtpPaneDockLeft || m_direction == xtpPaneDockRight;
|
|
BOOL bIndent = bVertical && (m_pLayout->m_wndPanels[xtpPaneDockTop] != NULL && !m_pLayout->m_wndPanels[xtpPaneDockTop]->IsEmpty());
|
|
|
|
int nPanelIndent = bIndent ? GetPanelHeight() : 0;
|
|
|
|
rcClient.top += nPanelIndent;
|
|
|
|
CXTPDockingPaneManager* pPaneManager = GetDockingPaneManager();
|
|
|
|
if (bVertical)
|
|
{
|
|
rcClient.top += pPaneManager->GetClientMargin();
|
|
}
|
|
else
|
|
{
|
|
rcClient.left += pPaneManager->GetClientMargin();
|
|
}
|
|
|
|
CRect rcWindow(rcClient);
|
|
|
|
m_pTabManagers->FreeAll();
|
|
|
|
CRect rcMargins = GetPaintManager()->GetAppearanceSet()->GetHeaderMargin();
|
|
|
|
int nMarginIndent = rcMargins.left + rcMargins.right + 8;
|
|
|
|
POSITION pos = GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)GetNext(pos);
|
|
if (pContainer->IsEmpty())
|
|
continue;
|
|
|
|
CAutoHidePanelTabManager* pManager = m_pTabManagers->AddManager();
|
|
|
|
POSITION posPane = pContainer->GetHeadPosition();
|
|
while (posPane)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)pContainer->GetNext(posPane);
|
|
|
|
CXTPTabManagerItem* pItem = pManager->Add();
|
|
|
|
pItem->SetData((DWORD_PTR)pPane);
|
|
if (pContainer->GetSelected() == pPane && pPaneManager->GetPaintManager()->m_bAutoHidePanelHighlightSelected) pManager->SetSelectedItem(pItem);
|
|
|
|
pItem->SetCaption(pPane->GetTabCaption());
|
|
pItem->SetColor(pPane->GetItemColor());
|
|
pItem->SetEnabled(pPane->GetEnabled() & xtpPaneEnableClient);
|
|
}
|
|
pManager->GetPaintManager()->RepositionTabControl(pManager, pDC, rcClient);
|
|
pManager->m_rcManager = rcClient;
|
|
|
|
if (bVertical)
|
|
rcClient.top += pManager->GetItemsLength() + nMarginIndent;
|
|
else
|
|
rcClient.left += pManager->GetItemsLength() + nMarginIndent;
|
|
}
|
|
|
|
if (pPaneManager->m_bShowPanelScrollButtons)
|
|
{
|
|
m_nItemsLength = (!bVertical ? rcClient.left - rcWindow.left : rcClient.top - rcWindow.top) - nMarginIndent;
|
|
|
|
CXTPTabManagerNavigateButton* pButtonLeft = FindNavigateButton(xtpTabNavigateButtonLeft);
|
|
CXTPTabManagerNavigateButton* pButtonRight = FindNavigateButton(xtpTabNavigateButtonRight);
|
|
|
|
BOOL bAddButton = !bVertical ? rcClient.left > rcClient.right : rcClient.top > rcClient.bottom;
|
|
|
|
if (bAddButton)
|
|
{
|
|
pButtonLeft->SetFlags(xtpTabNavigateButtonAlways);
|
|
pButtonRight->SetFlags(xtpTabNavigateButtonAlways);
|
|
|
|
GetPaintManager()->RepositionNavigateButtons(this, rcWindow);
|
|
}
|
|
else
|
|
{
|
|
pButtonLeft->SetFlags(xtpTabNavigateButtonNone);
|
|
pButtonRight->SetFlags(xtpTabNavigateButtonNone);
|
|
pButtonLeft->SetRect(CRect(0, 0, 0, 0));
|
|
pButtonRight->SetRect(CRect(0, 0, 0, 0));
|
|
m_nHeaderOffset = 0;
|
|
}
|
|
|
|
rcClient = rcWindow;
|
|
|
|
if (bAddButton)
|
|
{
|
|
if (m_nHeaderOffset < 0)
|
|
{
|
|
int nWindowEnd = bVertical ? rcWindow.bottom : rcWindow.right;
|
|
|
|
if (m_nItemsLength + m_nHeaderOffset < nWindowEnd - 24 - nMarginIndent - nPanelIndent)
|
|
{
|
|
m_nHeaderOffset = min(0, nWindowEnd - 24 - nMarginIndent - m_nItemsLength - nPanelIndent);
|
|
}
|
|
}
|
|
|
|
if (bVertical) rcClient.top += m_nHeaderOffset; else rcClient.left += m_nHeaderOffset;
|
|
|
|
for (int i = 0; i < m_pTabManagers->GetSize(); i++)
|
|
{
|
|
CAutoHidePanelTabManager* pManager = m_pTabManagers->GetAt(i);
|
|
|
|
if (bVertical)
|
|
rcClient.bottom = rcClient.top + pManager->GetItemsLength() + nMarginIndent;
|
|
else
|
|
rcClient.right = rcClient.left + pManager->GetItemsLength() + nMarginIndent;
|
|
|
|
pManager->GetPaintManager()->RepositionTabControl(pManager, pDC, rcClient);
|
|
pManager->m_rcManager = rcClient;
|
|
|
|
if (bVertical)
|
|
rcClient.top = rcClient.bottom;
|
|
else
|
|
rcClient.left = rcClient.right;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
XTPTabPosition CXTPDockingPaneAutoHidePanel::GetPosition() const
|
|
{
|
|
switch (GetDirection())
|
|
{
|
|
case xtpPaneDockLeft: return xtpTabPositionRight;
|
|
case xtpPaneDockRight: return xtpTabPositionLeft;
|
|
case xtpPaneDockTop: return xtpTabPositionBottom;
|
|
case xtpPaneDockBottom: return xtpTabPositionTop;
|
|
}
|
|
return xtpTabPositionTop;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::_InsertPane(CXTPDockingPaneBase* pPane)
|
|
{
|
|
m_lstPanes.AddTail(pPane);
|
|
|
|
pPane->SetParentContainer(this);
|
|
pPane->SetDockingSite(m_pDockingSite);
|
|
|
|
GetDockingPaneManager()->RecalcFrameLayout(this, TRUE);
|
|
|
|
pPane->OnParentContainerChanged(this);
|
|
|
|
if (pPane->GetType() == xtpPaneTypeTabbedContainer)
|
|
{
|
|
CWnd* pFocus = GetFocus();
|
|
if (((CXTPDockingPaneTabbedContainer*)pPane)->GetSafeHwnd() && pFocus->GetSafeHwnd() && (pFocus == ((CXTPDockingPaneTabbedContainer*)pPane) || ((CXTPDockingPaneTabbedContainer*)pPane)->IsChild(pFocus)))
|
|
GetDockingPaneManager()->GetSite()->SetFocus();
|
|
}
|
|
|
|
if (m_hWnd) Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::RemovePane(CXTPDockingPaneBase* pPane)
|
|
{
|
|
POSITION pos = m_lstPanes.Find(pPane);
|
|
ASSERT(pos);
|
|
|
|
m_lstPanes.RemoveAt(pos);
|
|
if (m_hWnd) Invalidate(FALSE);
|
|
GetDockingPaneManager()->RecalcFrameLayout(this, TRUE);
|
|
|
|
if (m_lstPanes.IsEmpty())
|
|
{
|
|
if (m_hWnd) DestroyWindow();
|
|
}
|
|
|
|
pPane->m_pParentContainer = NULL;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::Create(CWnd* pParent)
|
|
{
|
|
CWnd::Create(_T("XTPDockingPaneAutoHidePanel"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CXTPEmptyRect(), pParent, 0);
|
|
m_pDropTarget->Register(this);
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnSizeParentEx(CWnd* pParent, CRect& rect, LPVOID lParam)
|
|
{
|
|
AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
|
|
|
|
if (IsEmpty())
|
|
{
|
|
if (m_hWnd) DestroyWindow();
|
|
return;
|
|
}
|
|
|
|
if (!m_hWnd)
|
|
Create(pParent);
|
|
|
|
if (m_rcFrameRect != rect)
|
|
{
|
|
CloseActiveWindow();
|
|
m_rcFrameRect = rect;
|
|
}
|
|
|
|
int nHeight = GetPanelHeight();
|
|
|
|
CRect rcClient(rect);
|
|
switch (m_direction)
|
|
{
|
|
case xtpPaneDockLeft:
|
|
rcClient.right = rect.left = rect.left + nHeight;
|
|
break;
|
|
|
|
case xtpPaneDockRight:
|
|
rcClient.left = rect.right = rect.right - nHeight;
|
|
break;
|
|
|
|
case xtpPaneDockTop:
|
|
rcClient.bottom = rect.top = rect.top + nHeight;
|
|
break;
|
|
|
|
case xtpPaneDockBottom:
|
|
rcClient.top = rect.bottom = rect.bottom - nHeight;
|
|
break;
|
|
}
|
|
|
|
CClientDC dc(this);
|
|
CRect rcPanel(rcClient);
|
|
rcPanel.OffsetRect(-rcPanel.TopLeft());
|
|
RefreshManagersArray(&dc, rcPanel);
|
|
|
|
if (lpLayout->hDWP != NULL)
|
|
{
|
|
MoveWindow(rcClient);
|
|
Invalidate(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPDockingPaneAutoHidePanel, CWnd)
|
|
ON_WM_PAINT()
|
|
ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_RBUTTONUP()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
|
|
ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
|
|
END_MESSAGE_MAP()
|
|
|
|
LRESULT CXTPDockingPaneAutoHidePanel::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
|
|
{
|
|
CDC* pDC = CDC::FromHandle((HDC)wParam);
|
|
if (pDC)
|
|
{
|
|
OnDraw(pDC);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnPaint()
|
|
{
|
|
CPaintDC dcPaint(this);
|
|
CXTPBufferDC dc(dcPaint);
|
|
OnDraw(&dc);
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnDraw(CDC* pDC)
|
|
{
|
|
CXTPClientRect rc(this);
|
|
|
|
CXTPTabPaintManager* pPaintManager = GetPaintManager();
|
|
|
|
CXTPPaintManagerColorGradient& clr = pPaintManager->GetColorSet()->m_clrAutoHideFace;
|
|
|
|
if (clr.clrDark == clr.clrLight)
|
|
{
|
|
pDC->FillSolidRect(rc, clr.clrDark);
|
|
}
|
|
else
|
|
{
|
|
CRect rcFill(rc);
|
|
|
|
if (m_direction == xtpPaneDockRight)
|
|
{
|
|
rcFill.left -= CXTPClientRect(GetParent()).Width() - rcFill.Width();
|
|
}
|
|
|
|
rcFill.right = rcFill.left + max(rcFill.Width(), GetSystemMetrics(SM_CXFULLSCREEN) / 2);
|
|
XTPDrawHelpers()->GradientFill(pDC, rcFill, clr.clrLight, clr.clrDark, TRUE, rc);
|
|
}
|
|
|
|
if (FindNavigateButton(xtpTabNavigateButtonLeft)->GetFlags() == xtpTabNavigateButtonAlways)
|
|
{
|
|
CRect rcButton(FindNavigateButton(xtpTabNavigateButtonLeft)->GetRect());
|
|
pPaintManager->DrawTabControl(this, pDC, rc);
|
|
|
|
if (IsHorizontalPosition())
|
|
pDC->ExcludeClipRect(rcButton.left, 0, rc.right, rc.bottom);
|
|
else
|
|
pDC->ExcludeClipRect(0, rcButton.top, rc.right, rc.bottom);
|
|
pPaintManager->m_bClipHeader = FALSE;
|
|
}
|
|
|
|
m_pTabManagers->Draw(pDC);
|
|
}
|
|
|
|
CXTPTabManagerItem* CXTPDockingPaneAutoHidePanel::GetPaneTab(CXTPDockingPane* pPane) const
|
|
{
|
|
for (int i = 0; i < m_pTabManagers->GetSize(); i++)
|
|
{
|
|
CAutoHidePanelTabManager* pTabManager = m_pTabManagers->GetAt(i);
|
|
|
|
for (int j = 0; j < pTabManager->GetItemCount(); j++)
|
|
{
|
|
CXTPTabManagerItem* pItem = pTabManager->GetItem(j);
|
|
|
|
if ((CXTPDockingPane*)pItem->GetData() == pPane)
|
|
{
|
|
return pItem;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CXTPDockingPane* CXTPDockingPaneAutoHidePanel::HitTest(CPoint point) const
|
|
{
|
|
for (int i = 0; i < m_pTabManagers->GetSize(); i++)
|
|
{
|
|
CXTPTabManagerItem* pItem = m_pTabManagers->GetAt(i)->HitTest(point);
|
|
if (pItem)
|
|
{
|
|
return (CXTPDockingPane*)pItem->GetData();
|
|
}
|
|
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::CloseActiveWindows()
|
|
{
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
SAFE_CALLPTR(m_pLayout->m_wndPanels[i], CloseActiveWindow());
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::CloseActiveWindow(BOOL bDelayed)
|
|
{
|
|
if (!m_bCloseActiveWindow)
|
|
return;
|
|
|
|
if (m_pActiveWnd)
|
|
{
|
|
if (m_pActiveWnd->m_pPane && m_pActiveWnd->m_pPane->GetSelected() != NULL)
|
|
{
|
|
if (GetDockingPaneManager()->NotifyAction(xtpPaneActionCollapsing, m_pActiveWnd->m_pPane->GetSelected()))
|
|
return;
|
|
|
|
GetDockingPaneManager()->NotifyAction(xtpPaneActionCollapsed,
|
|
m_pActiveWnd->m_pPane->GetSelected());
|
|
}
|
|
|
|
if (bDelayed)
|
|
{
|
|
// let the window close itself
|
|
if (m_pActiveWnd->m_pPane)
|
|
{
|
|
m_pActiveWnd->m_pPane->ShowWindow(SW_HIDE);
|
|
m_pActiveWnd->m_pPane->SetDockingSite(GetDockingPaneManager()->GetSite());
|
|
m_pActiveWnd->m_pPane = 0;
|
|
}
|
|
m_pActiveWnd->SetTimer(TID_CLOSE, 50, NULL);
|
|
}
|
|
else
|
|
{
|
|
m_pActiveWnd->CloseWindow();
|
|
}
|
|
|
|
m_pActiveWnd = 0;
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::ShowPane(CXTPDockingPane* pPane, BOOL bSetFocus)
|
|
{
|
|
if (m_pActiveWnd && m_pActiveWnd->m_pPane && m_pActiveWnd->m_pPane->GetSelected() == pPane)
|
|
{
|
|
if (bSetFocus) m_pActiveWnd->m_pPane->SelectPane(pPane, TRUE, FALSE);
|
|
|
|
if (m_pActiveWnd->m_bSlideOut)
|
|
{
|
|
m_pActiveWnd->OnTimer(TID_CHECKACTIVE);
|
|
}
|
|
return;
|
|
}
|
|
|
|
CloseActiveWindows();
|
|
|
|
if (GetDockingPaneManager()->NotifyAction(xtpPaneActionExpanding, pPane))
|
|
return;
|
|
|
|
CXTPDockingPaneTabbedContainer* pContainer = ((CXTPDockingPaneTabbedContainer*)pPane->m_pParentContainer);
|
|
|
|
ASSERT(pContainer);
|
|
if (!pContainer)
|
|
return;
|
|
ASSERT(pContainer->GetType() == xtpPaneTypeTabbedContainer);
|
|
|
|
pContainer->SelectPane(pPane, FALSE, TRUE);
|
|
CXTPDockingPaneAutoHideWnd* pActiveWnd = new CXTPDockingPaneAutoHideWnd(this, pContainer);
|
|
|
|
if (bSetFocus) pContainer->SelectPane(pPane, TRUE, FALSE);
|
|
|
|
if (m_hWnd) Invalidate(FALSE);
|
|
GetDockingPaneManager()->RecalcFrameLayout(this);
|
|
|
|
m_pActiveWnd = pActiveWnd;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnLButtonDown(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
if (m_pHighlightedNavigateButton)
|
|
{
|
|
m_pHighlightedNavigateButton->PerformClick(m_hWnd, point);
|
|
return;
|
|
}
|
|
|
|
CXTPDockingPane* pPane = HitTest(point);
|
|
if (pPane)
|
|
{
|
|
if (m_pActiveWnd && m_pActiveWnd->m_pPane->GetSelected() == pPane)
|
|
{
|
|
pPane->SetFocus();
|
|
|
|
}
|
|
else
|
|
{
|
|
ShowPane(pPane);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnRButtonDown(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
CXTPDockingPane* pPane = HitTest(point);
|
|
if (pPane)
|
|
{
|
|
GetDockingPaneManager()->NotifyOwner(XTP_DPN_RCLICK, (LPARAM)(CXTPDockingPaneBase*)pPane);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnRButtonUp(UINT /*nFlags*/, CPoint point)
|
|
{
|
|
XTP_DOCKINGPANE_CLICK menu;
|
|
menu.pPane = HitTest(point);
|
|
menu.pContainer = this;
|
|
ClientToScreen(&point);
|
|
menu.pt = point;
|
|
menu.rcExclude.SetRectEmpty();
|
|
|
|
if (GetDockingPaneManager()->NotifyOwner(XTP_DPN_CONTEXTMENU, (LPARAM)&menu))
|
|
return;
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
PerformMouseMove(m_hWnd, point);
|
|
|
|
if (m_pHighlightedNavigateButton)
|
|
{
|
|
point = CPoint(-1, -1);
|
|
}
|
|
|
|
|
|
for (int i = 0; i < m_pTabManagers->GetSize(); i++)
|
|
{
|
|
m_pTabManagers->GetAt(i)->PerformMouseMove(m_hWnd, point);
|
|
}
|
|
|
|
|
|
|
|
CXTPDockingPane* pPane = HitTest(point);
|
|
if (pPane)
|
|
{
|
|
TRACKMOUSEEVENT tme =
|
|
{
|
|
sizeof(TRACKMOUSEEVENT), TME_HOVER | TME_LEAVE, m_hWnd, CXTPDockingPaneAutoHideWnd::m_nMouseHoverDelay
|
|
};
|
|
_TrackMouseEvent(&tme);
|
|
|
|
}
|
|
CWnd::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnMouseLeave()
|
|
{
|
|
OnMouseMove(0, CPoint(-1, -1));
|
|
}
|
|
|
|
LRESULT CXTPDockingPaneAutoHidePanel::OnMouseHover(WPARAM, LPARAM lParam)
|
|
{
|
|
if (m_pHighlightedNavigateButton)
|
|
return 1;
|
|
|
|
CPoint point(lParam);
|
|
CXTPDockingPane* pPane = HitTest(point);
|
|
if (pPane)
|
|
{
|
|
if (!CXTPDrawHelpers::IsTopParentActive(m_hWnd) || (m_pActiveWnd && m_pActiveWnd->m_pPane->GetSelected() == pPane))
|
|
return 1;
|
|
|
|
if (pPane->GetOptions() & xtpPaneNoHoverShow)
|
|
return 1;
|
|
|
|
|
|
ShowPane(pPane, FALSE);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneAutoHidePanel::Copy(CXTPDockingPaneBase* pCloneBase, CXTPPaneToPaneMap* pMap, DWORD /*dwIgnoredOptions*/)
|
|
{
|
|
CXTPDockingPaneAutoHidePanel* pClone = (CXTPDockingPaneAutoHidePanel*)pCloneBase;
|
|
|
|
ASSERT(pClone);
|
|
if (!pClone)
|
|
return;
|
|
|
|
m_direction = pClone->m_direction;
|
|
m_pDockingSite = GetDockingPaneManager()->GetSite();
|
|
|
|
POSITION pos = pClone->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = pClone->GetNext(pos);
|
|
if (!pPane->IsEmpty() || pMap)
|
|
{
|
|
_InsertPane(pPane->Clone(m_pLayout, pMap));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::InvalidatePane(BOOL /*bSelectionChanged*/)
|
|
{
|
|
if (!m_hWnd)
|
|
return;
|
|
|
|
CClientDC dc(this);
|
|
CXTPClientRect rcPanel(this);
|
|
|
|
RefreshManagersArray(&dc, rcPanel);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnChildContainerChanged(CXTPDockingPaneBase* /*pContainer*/)
|
|
{
|
|
if (m_pActiveWnd)
|
|
{
|
|
if (!m_bCloseActiveWindow)
|
|
{
|
|
GetDockingPaneManager()->RecalcFrameLayout(this);
|
|
|
|
m_pActiveWnd->RecalcLayout(TRUE);
|
|
}
|
|
else
|
|
{
|
|
CloseActiveWindow(GetDockingPaneManager()->m_bAttachingPane);
|
|
|
|
GetDockingPaneManager()->RecalcFrameLayout(this, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::DeletePane()
|
|
{
|
|
InternalRelease();
|
|
}
|
|
|
|
void CXTPDockingPaneAutoHidePanel::OnFinalRelease()
|
|
{
|
|
if (m_hWnd != NULL)
|
|
DestroyWindow();
|
|
|
|
CCmdTarget::OnFinalRelease();
|
|
}
|
|
|