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.

1175 lines
26 KiB
C++

2 years ago
// XTPDockingPaneMiniWnd.cpp : implementation of the CXTPDockingPaneMiniWnd 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/XTPDrawHelpers.h"
#include "Common/XTPToolTipContext.h"
#include "Common/XTPResourceManager.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPColorManager.h"
#include "TabManager/XTPTabManager.h"
#include "XTPDockingPaneDefines.h"
#include "XTPDockingPaneBase.h"
#include "XTPDockingPaneBaseContainer.h"
#include "XTPDockingPaneMiniWnd.h"
#include "XTPDockingPane.h"
#include "XTPDockingPaneSplitterContainer.h"
#include "XTPDockingPaneTabbedContainer.h"
#include "XTPDockingPaneContext.h"
#include "XTPDockingPaneManager.h"
#include "XTPDockingPaneLayout.h"
#include "XTPDockingPanePaintManager.h"
#include "XTPDockingPaneAutoHidePanel.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BOOL CXTPDockingPaneMiniWnd::m_bShowPinButton = TRUE;
#define TID_NCLEAVE 2345
#define TID_CHECKACTIVE 1
#define TID_SLIDEIN 2
#define TID_SLIDEOUT 3
#ifndef LWA_ALPHA
#define LWA_ALPHA 0x00000002
#endif
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000
#endif
IMPLEMENT_DYNAMIC(CXTPDockingPaneMiniWnd, CMiniFrameWnd)
AFX_INLINE int ResetStepsCount()
{
if (CXTPDockingPaneAutoHideWnd::m_nAnimationInterval == 0)
return 1;
return max(1, CXTPDockingPaneAutoHideWnd::m_nAnimationDuration / CXTPDockingPaneAutoHideWnd::m_nAnimationInterval);
}
CXTPDockingPaneMiniWnd::CXTPDockingPaneMiniWnd(CXTPDockingPaneLayout* pLayout)
: CXTPDockingPaneBase(xtpPaneTypeMiniWnd, pLayout)
{
m_pTopContainer = NULL;
m_pCaptionButtons = new CXTPDockingPaneCaptionButtons();
m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_CLOSE, this));
m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_AUTOHIDE, this));
m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_MENU, this));
m_bSlideOut = m_bExpanded = m_bCollapsed = FALSE;
m_nExpandedHeight = 0;
m_nSlideStep = 0;
m_nStepsCount = ResetStepsCount();
m_bDelayInvalidate = FALSE;
m_nDeactivationCount = 0;
}
void CXTPDockingPaneMiniWnd::Init(CXTPDockingPaneBase* pPane, CRect rc)
{
m_rcWindow = rc;
CreateContainer();
if (pPane->GetType() == xtpPaneTypeDockingPane)
{
CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)GetDockingPaneManager()->
OnCreatePane(xtpPaneTypeTabbedContainer, m_pLayout);
pContainer->Init((CXTPDockingPane*)pPane, this);
pPane = pContainer;
}
m_pTopContainer = (CXTPDockingPaneSplitterContainer*)GetDockingPaneManager()->
OnCreatePane(xtpPaneTypeSplitterContainer, m_pLayout);
m_pTopContainer->Init(pPane, TRUE, this);
m_pTopContainer->m_pParentContainer = this;
m_bDelayInvalidate = TRUE;
PostMessage(WM_IDLEUPDATECMDUI);
DelayRecalcLayout();
OnFocusChanged();
}
CXTPDockingPaneMiniWnd::~CXTPDockingPaneMiniWnd()
{
DestroyWindow();
}
void CXTPDockingPaneMiniWnd::Copy(CXTPDockingPaneBase* pCloneBase, CXTPPaneToPaneMap* pMap, DWORD /*dwIgnoredOptions*/)
{
CXTPDockingPaneMiniWnd* pClone = (CXTPDockingPaneMiniWnd*)pCloneBase;
ASSERT(pMap);
m_pTopContainer = (CXTPDockingPaneSplitterContainer*)pClone->m_pTopContainer->Clone(m_pLayout, pMap);
m_pTopContainer->m_pParentContainer = this;
m_pTopContainer->m_pDockingSite = this;
m_rcWindow = pClone->m_rcWindow;
if (pClone->m_hWnd) ::GetWindowRect(pClone->m_hWnd, &m_rcWindow);
m_bCollapsed = ((CXTPDockingPaneMiniWnd*)pClone)->m_bCollapsed;
m_nExpandedHeight = ((CXTPDockingPaneMiniWnd*)pClone)->m_nExpandedHeight;
if (m_bCollapsed && pClone->m_hWnd)
{
m_rcWindow.bottom = m_rcWindow.top + GetPaintManager()->GetCaptionHeight() + 8;
}
if (!m_pLayout->IsUserLayout())
{
CreateContainer();
m_pTopContainer->OnParentContainerChanged(m_pTopContainer);
OnChildContainerChanged(m_pTopContainer);
}
}
void CXTPDockingPaneMiniWnd::RemovePane(CXTPDockingPaneBase* pPane)
{
ASSERT(pPane == m_pTopContainer);
pPane->m_pParentContainer = NULL;
m_pTopContainer = NULL;
if (m_hWnd) ShowWindow(SW_HIDE);
if (m_bCollapsed)
OnPinButtonClick();
}
void CXTPDockingPaneMiniWnd::InvalidatePane(BOOL /*bSelectionChanged*/)
{
if (!m_pTopContainer)
return;
if (!m_hWnd)
return;
CXTPDockingPaneBaseList lstTabbed;
FindPane(xtpPaneTypeTabbedContainer, &lstTabbed);
int nCount = (int)lstTabbed.GetCount();
POSITION pos = lstTabbed.GetHeadPosition();
while (pos)
{
CXTPDockingPaneBase* pPane = lstTabbed.GetNext(pos);
ASSERT(pPane->GetType() == xtpPaneTypeTabbedContainer);
((CXTPDockingPaneTabbedContainer*)pPane)->ShowTitle(nCount != 1);
}
CString strTitle = (nCount != 1) ? GetDockingPaneManager()->m_strFloatingFrameCaption : ((CXTPDockingPaneTabbedContainer*)lstTabbed.GetHead())->GetTitle();
SetWindowText(strTitle);
if (nCount > 0)
{
BOOL bEnabled = FALSE;
CXTPDockingPaneBaseList lstChilds;
FindPane(xtpPaneTypeDockingPane, &lstChilds);
pos = lstChilds.GetHeadPosition();
while (pos)
{
CXTPDockingPaneBase* pPane = lstChilds.GetNext(pos);
if ((((CXTPDockingPane*)pPane)->GetOptions() & xtpPaneNoCloseable) == 0)
bEnabled = TRUE;
}
if (!bEnabled || !m_bCloseEnabled)
{
CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | (bEnabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED));
m_bCloseEnabled = bEnabled;
}
if ((GetStyle() & WS_CHILD) == 0)
UpdatePosition();
if ((GetStyle() & WS_VISIBLE) == 0)
ShowWindow(SW_SHOWNOACTIVATE);
}
SendMessage(WM_NCPAINT);
OnFocusChanged();
}
void CXTPDockingPaneMiniWnd::UpdatePosition()
{
CXTPWindowRect rc(this);
CSize sz = rc.Size();
if (IsThemed())
{
MINMAXINFO mmi;
ZeroMemory(&mmi, sizeof(mmi));
mmi.ptMaxTrackSize.x = 32000;
mmi.ptMaxTrackSize.y = 32000;
GetMinMaxInfo(&mmi);
sz.cx = max(min(sz.cx, mmi.ptMaxTrackSize.x), mmi.ptMinTrackSize.x);
sz.cy = max(min(sz.cy, mmi.ptMaxTrackSize.y), mmi.ptMinTrackSize.y);
}
MoveWindow(rc.left, rc.top, sz.cx, sz.cy);
}
void CXTPDockingPaneMiniWnd::CreateContainer()
{
if (!m_hWnd)
{
Create(m_rcWindow);
}
}
void CXTPDockingPaneMiniWnd::OnChildContainerChanged(CXTPDockingPaneBase* /*pContainer*/)
{
if (!m_hWnd)
return;
if (m_pTopContainer == NULL || m_pTopContainer->IsEmpty())
{
DestroyWindow();
}
else
{
m_bDelayInvalidate = TRUE;
PostMessage(WM_IDLEUPDATECMDUI);
}
}
void CXTPDockingPaneMiniWnd::RecalcLayout(BOOL /*bNotify*/)
{
if (m_pTopContainer == NULL)
return;
if (m_bInRecalcLayout)
return;
m_bInRecalcLayout = TRUE;
m_nIdleFlags &= ~(idleLayout | idleNotify);
if (m_pTopContainer->IsEmpty())
{
ShowWindow(SW_HIDE);
if (m_bCollapsed)
OnPinButtonClick();
}
else
{
//ShowWindow(SW_SHOW);
AFX_SIZEPARENTPARAMS layout;
layout.bStretch = TRUE;
GetClientRect(&layout.rect);
layout.hDWP = ::BeginDeferWindowPos(8); // reasonable guess
m_pTopContainer->OnSizeParent(this, layout.rect, &layout);
if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP))
{
TRACE0("Warning: DeferWindowPos failed - low system resources.\n");
}
CWnd::GetWindowRect(&m_pTopContainer->m_rcWindow);
ScreenToClient(&m_pTopContainer->m_rcWindow);
}
GetDockingPaneManager()->SyncPanesState();
m_bInRecalcLayout = FALSE;
}
BOOL CXTPDockingPaneMiniWnd::Create(CRect rc)
{
DWORD dwStyle = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_BORDER |
MFS_BLOCKSYSMENU | WS_THICKFRAME | (GetDockingPaneManager()->m_bSyncActiveFloatingFrames ? MFS_SYNCACTIVE : 0);
DWORD dwExStyle = 0;
if (GetDockingPaneManager()->IsLayoutRTL())
{
dwExStyle = WS_EX_LAYOUTRTL;
}
CXTPDockingPaneContext::EnsureVisible(rc);
CWnd* pParentWnd = GetDockingPaneManager()->GetSite();
if (pParentWnd->GetStyle() & WS_CHILD) pParentWnd = AfxGetMainWnd();
if (!CMiniFrameWnd::CreateEx(dwExStyle,
_T("XTPDockingPaneMiniWnd"), _T(""), dwStyle, rc, pParentWnd))
{
return FALSE;
}
CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
CString strHide;
if (strHide.LoadString(AFX_IDS_HIDE))
{
pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
pSysMenu->AppendMenu(MF_STRING | MF_ENABLED, SC_CLOSE, strHide);
}
m_bCloseEnabled = TRUE;
if (IsThemed())
{
ModifyStyle(WS_BORDER | WS_THICKFRAME, 0, SWP_FRAMECHANGED);
}
SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
UpdateWindowOpacity();
return TRUE;
}
BEGIN_MESSAGE_MAP(CXTPDockingPaneMiniWnd, CMiniFrameWnd)
ON_WM_CLOSE()
ON_WM_NCLBUTTONDOWN()
ON_WM_NCRBUTTONUP()
ON_WM_NCLBUTTONDBLCLK()
ON_WM_DESTROY()
ON_WM_CONTEXTMENU()
ON_WM_NCHITTEST_EX()
ON_WM_NCPAINT()
ON_WM_NCCALCSIZE()
ON_WM_NCMOUSEMOVE()
ON_WM_TIMER()
ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
ON_WM_GETMINMAXINFO()
ON_WM_SETFOCUS()
ON_WM_NCACTIVATE()
ON_WM_SIZING()
END_MESSAGE_MAP()
void CXTPDockingPaneMiniWnd::OnSizing(UINT nSide, LPRECT lpRect)
{
CMiniFrameWnd::OnSizing(nSide, lpRect);
GetDockingPaneManager()->GetDockingContext()->OnSizingFloatingFrame(this, nSide, lpRect);
}
void CXTPDockingPaneMiniWnd::UpdateWindowOpacity()
{
if (!GetSafeHwnd())
return;
CXTPDockingPaneManager::PFNSETLAYEREDWINDOWATTRIBUTES pfnSetLayeredWindowAttributes =
GetDockingPaneManager()->m_pfnSetLayeredWindowAttributes;
if (!pfnSetLayeredWindowAttributes)
return;
int nFloatingFramesOpacity = GetDockingPaneManager()->m_nFloatingFramesOpacity;
if (nFloatingFramesOpacity == 255)
{
ModifyStyleEx(WS_EX_LAYERED, 0);
return;
}
if (!m_bActive)
{
ModifyStyleEx(0, WS_EX_LAYERED);
pfnSetLayeredWindowAttributes(m_hWnd, 0x00, (BYTE)nFloatingFramesOpacity, LWA_ALPHA);
}
else
{
pfnSetLayeredWindowAttributes(m_hWnd, 0x00, (BYTE)255, LWA_ALPHA);
}
}
void CXTPDockingPaneMiniWnd::OnFocusChanged()
{
if (GetSafeHwnd())
{
CWnd* pFocus = GetFocus();
BOOL bActive = (pFocus->GetSafeHwnd() && (pFocus == this || IsChild(pFocus) ||
(pFocus->GetOwner()->GetSafeHwnd() && IsChild(pFocus->GetOwner()))));
if (bActive != m_bActive)
{
m_bActive = bActive;
if (IsThemed())
{
SendMessage(WM_NCPAINT);
}
UpdateWindowOpacity();
}
}
}
void CXTPDockingPaneMiniWnd::OnIdleUpdateCmdUI()
{
if (!GetSafeHwnd())
return;
if (m_bDelayInvalidate)
{
m_bDelayInvalidate = FALSE;
InvalidatePane(FALSE);
}
CMiniFrameWnd::OnIdleUpdateCmdUI();
}
void CXTPDockingPaneMiniWnd::OnClose()
{
if (m_pTopContainer)
{
m_pCaptionButtons->CheckForMouseOver(CPoint(-1, -1));
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
CXTPDockingPaneBaseList lst;
FindPane(xtpPaneTypeDockingPane, &lst);
POSITION pos = lst.GetHeadPosition();
while (pos)
{
CXTPDockingPane* pPane = (CXTPDockingPane*)lst.GetNext(pos);
if ((pPane->GetOptions() & xtpPaneNoCloseable) != 0)
continue;
pPane->InternalAddRef();
if (!pManager->NotifyAction(xtpPaneActionClosing, pPane))
{
pPane->Close();
pManager->NotifyAction(xtpPaneActionClosed, pPane);
}
pPane->InternalRelease();
}
}
}
void CXTPDockingPaneMiniWnd::OnSetFocus(CWnd* pOldWnd)
{
CMiniFrameWnd::OnSetFocus(pOldWnd);
if (m_pTopContainer == 0)
return;
if (!m_pLayout || !m_pLayout->IsValid())
return;
CXTPDockingPaneBaseList lst;
FindPane(xtpPaneTypeTabbedContainer, &lst);
if (lst.GetCount() == 1)
{
CXTPDockingPane* pPane =
((CXTPDockingPaneTabbedContainer*)lst.GetHead())->GetSelected();
if (pPane)
{
pPane->SetFocus();
}
}
GetDockingPaneManager()->UpdatePanes();
}
void CXTPDockingPaneMiniWnd::PostNcDestroy()
{
// prevent auto deleting
}
void CXTPDockingPaneMiniWnd::FindPane(XTPDockingPaneType type, CXTPDockingPaneBaseList* pList) const
{
if (GetType() == type)
{
pList->AddTail((CXTPDockingPaneBase*)this);
}
else if (m_pTopContainer)
{
m_pTopContainer->FindPane(type, pList);
}
}
void CXTPDockingPaneMiniWnd::OnContextMenu(CWnd* pWnd, CPoint point)
{
CXTPDockingPaneBaseList lst;
FindPane(xtpPaneTypeTabbedContainer, &lst);
CXTPDockingPane* pSelectedPane = 0;
if (lst.GetCount() == 1)
{
pSelectedPane = ((CXTPDockingPaneTabbedContainer*)lst.GetHead())->GetSelected();
}
else
{
POSITION pos = lst.GetHeadPosition();
while (pos)
{
CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)lst.GetNext(pos);
if (pContainer->IsActive())
{
pSelectedPane = pContainer->GetSelected();
break;
}
}
}
if (pSelectedPane) pSelectedPane->SetFocus();
XTP_DOCKINGPANE_CLICK menu;
menu.pPane = pSelectedPane;
menu.pt = point;
menu.rcExclude.SetRectEmpty();
menu.pContainer = this;
if (GetDockingPaneManager()->NotifyOwner(XTP_DPN_CONTEXTMENU, (LPARAM)&menu))
return;
CMiniFrameWnd::OnContextMenu(pWnd, point);
}
void CXTPDockingPaneMiniWnd::OnNcRButtonUp(UINT nHitTest, CPoint point)
{
if (IsThemed() && (nHitTest == HTCAPTION))
{
OnContextMenu(this, point);
return;
}
CMiniFrameWnd::OnNcRButtonUp(nHitTest, point);
}
void CXTPDockingPaneMiniWnd::OnNcLButtonDblClk(UINT nHitTest, CPoint /*point*/)
{
if (nHitTest == HTCAPTION)
{
if (m_bCollapsed)
OnPinButtonClick();
else
GetDockingPaneManager()->ToggleDocking(m_pTopContainer);
}
}
void CXTPDockingPaneMiniWnd::OnDestroy()
{
::GetWindowRect(m_hWnd, &m_rcWindow);
CWnd::OnDestroy();
}
BOOL CXTPDockingPaneMiniWnd::IsThemed() const
{
return GetDockingPaneManager()->IsThemedFloatingFrames();
}
//////////////////////////////////////////////////////////////////////////
// Themed methods.
LRESULT CXTPDockingPaneMiniWnd::OnNcHitTest(CPoint point)
{
LRESULT nHitTest = (LRESULT)CMiniFrameWnd::OnNcHitTest(point);
if (!IsThemed())
return nHitTest;
CXTPWindowRect rcWindow(this);
CRect rcBorders = rcWindow;
rcBorders.DeflateRect(3, 3);
if (rcWindow.PtInRect(point) && !rcBorders.PtInRect(point))
{
int ht = 0;
if (point.y < rcBorders.top)
ht = (HTTOP - HTSIZEFIRST + 1);
else if (point.y >= rcBorders.bottom)
ht = (HTBOTTOM - HTSIZEFIRST + 1);
if (point.x < rcBorders.left)
ht += (HTLEFT - HTSIZEFIRST + 1);
else if (point.x >= rcBorders.right)
ht += (HTRIGHT - HTSIZEFIRST + 1);
return (LRESULT)(ht + HTSIZEFIRST - 1);
}
if (nHitTest == HTNOWHERE)
{
int nPoint = point.y - rcWindow.top;
if (nPoint < GetPaintManager()->GetCaptionHeight() + 4)
return HTCAPTION;
}
return nHitTest;
}
void CXTPDockingPaneMiniWnd::RedrawPane()
{
if (!IsThemed())
return;
if (GetSafeHwnd())
::InvalidateRect(GetSafeHwnd(), 0, FALSE);
SendMessage(WM_NCPAINT);
}
void CXTPDockingPaneMiniWnd::OnNcPaint()
{
if (IsThemed())
{
CWindowDC dc(this);
CRect rcClient;
GetClientRect(rcClient);
CRect rcWindow;
GetWindowRect(rcWindow);
ScreenToClient(rcWindow);
rcClient.OffsetRect(-rcWindow.left, -rcWindow.top);
dc.ExcludeClipRect(rcClient);
CXTPDockingPanePaintManager* pPaintManager = GetPaintManager();
CXTPWindowRect rc(this);
rc.OffsetRect(-rc.TopLeft());
pPaintManager->DrawFloatingFrame(&dc, this, rc);
}
else
{
Default();
}
}
BOOL CXTPDockingPaneMiniWnd::OnNcActivate(BOOL bActive)
{
if (IsThemed())
{
return TRUE;
}
return CMiniFrameWnd::OnNcActivate(bActive);
}
void CXTPDockingPaneMiniWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
if (IsThemed())
{
int nSize = 3;
lpncsp->rgrc[0].left += nSize;
lpncsp->rgrc[0].top += nSize;
lpncsp->rgrc[0].right -= nSize;
lpncsp->rgrc[0].bottom -= nSize;
int nTitleFont = GetPaintManager()->GetCaptionHeight();
lpncsp->rgrc[0].top += nTitleFont + 2;
return;
}
CMiniFrameWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
}
void CXTPDockingPaneMiniWnd::OnNcMouseMove(UINT nHitTest, CPoint point)
{
CMiniFrameWnd::OnNcMouseMove(nHitTest, point);
if (IsThemed())
{
CXTPDrawHelpers::ScreenToWindow(this, &point);
if (m_pCaptionButtons->CheckForMouseOver(point))
{
SetTimer (TID_NCLEAVE, 100, NULL);
}
Expand();
}
}
void CXTPDockingPaneMiniWnd::Collapse(BOOL bDelay)
{
m_nSlideStep = m_nStepsCount = ResetStepsCount();
CWnd::GetWindowRect(&m_rcWindow);
m_nExpandedHeight = m_rcWindow.Height();
m_bCollapsed = TRUE;
m_bExpanded = TRUE;
if (!bDelay)
{
if (!OnAction(xtpPaneActionCollapsing))
{
m_nSlideStep = 0;
DoSlideStep(FALSE);
KillTimer(TID_SLIDEOUT);
KillTimer(TID_CHECKACTIVE);
OnAction(xtpPaneActionCollapsed);
return;
}
}
if (m_bSlideOut)
{
m_bSlideOut = FALSE;
KillTimer(TID_SLIDEOUT);
OnAction(xtpPaneActionCollapsed);
}
m_nDeactivationCount = 6;
SetTimer(TID_CHECKACTIVE, 100, NULL);
}
void CXTPDockingPaneMiniWnd::OnCaptionButtonClick(CXTPDockingPaneCaptionButton* pButton)
{
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_CLOSE)
{
OnClose();
return;
}
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_AUTOHIDE)
{
OnPinButtonClick();
return;
}
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_MENU)
{
}
}
BOOL CXTPDockingPaneMiniWnd::OnCaptionButtonDown(CXTPDockingPaneCaptionButton* pButton)
{
switch (pButton->GetID())
{
case XTP_IDS_DOCKINGPANE_MENU:
CXTPDockingPane* pSelectedPane = GetSelectedPane();
if (pSelectedPane)
{
m_bActive = TRUE;
CXTPDockingPaneManager* pManager = GetDockingPaneManager();
XTP_DOCKINGPANE_CLICK menu;
menu.pContainer = this;
menu.rcExclude = pButton->GetRect();
CXTPWindowRect rcWindow(this);
if (GetExStyle() & WS_EX_LAYOUTRTL)
{
menu.rcExclude.OffsetRect(-menu.rcExclude.left + rcWindow.right - menu.rcExclude.right, rcWindow.top);
menu.pt = CPoint(menu.rcExclude.right, menu.rcExclude.bottom);
}
else
{
menu.rcExclude.OffsetRect(rcWindow.left, rcWindow.top);
menu.pt = CPoint(menu.rcExclude.left, menu.rcExclude.bottom);
}
menu.pPane = pSelectedPane;
pButton->m_bPressed = TRUE;
SendMessage(WM_NCPAINT);
pManager->NotifyOwner(XTP_DPN_CONTEXTMENU, (LPARAM)&menu);
pButton->m_bPressed = FALSE;
if (m_hWnd) SendMessage(WM_NCPAINT);
}
return TRUE;
}
return FALSE;
}
BOOL CXTPDockingPaneMiniWnd::OnAction(XTPDockingPaneAction action)
{
if (m_pTopContainer)
{
return m_pTopContainer->OnAction(action);
}
return FALSE;
}
void CXTPDockingPaneMiniWnd::OnPinButtonClick()
{
if (!m_hWnd)
return;
BOOL bPinning = m_bCollapsed;
if (OnAction(bPinning ? xtpPaneActionPinning : xtpPaneActionUnpinning))
return;
if (!m_bCollapsed)
{
Collapse(TRUE);
}
else
{
if (m_nStepsCount != m_nSlideStep)
{
CXTPWindowRect rcWindow(this);
SetWindowPos(0, 0, 0, rcWindow.Width(), m_nExpandedHeight, SWP_NOZORDER | SWP_NOMOVE);
}
m_bCollapsed = FALSE;
m_bExpanded = FALSE;
KillTimer(TID_CHECKACTIVE);
KillTimer(TID_SLIDEOUT);
}
SendMessage(WM_NCPAINT);
OnAction(bPinning ? xtpPaneActionPinned : xtpPaneActionUnpinned);
}
void CXTPDockingPaneMiniWnd::DoSlideStep(BOOL bActivate)
{
int nMinHeight = GetPaintManager()->GetCaptionHeight() + 8;
CXTPWindowRect rc(this);
rc.bottom = rc.top + max(nMinHeight, m_nSlideStep * m_nExpandedHeight / m_nStepsCount);
SetWindowPos(&CWnd::wndTop, rc.left, rc.top, rc.Width(), rc.Height(), (!bActivate ? SWP_NOZORDER | SWP_NOACTIVATE : SWP_NOACTIVATE));
Invalidate(FALSE);
}
CXTPDockingPane* CXTPDockingPaneMiniWnd::GetSelectedPane() const
{
if (!m_pTopContainer)
return 0;
CXTPDockingPaneBaseList lst;
FindPane(xtpPaneTypeTabbedContainer, &lst);
int nCount = (int)lst.GetCount();
if (nCount != 1)
return 0;
return ((CXTPDockingPaneTabbedContainer*)lst.GetHead())->GetSelected();
}
BOOL CXTPDockingPaneMiniWnd::IsCaptionButtonVisible(CXTPDockingPaneCaptionButton* pButton)
{
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_CLOSE)
return m_bCloseEnabled;
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_AUTOHIDE)
{
pButton->SetState(m_bCollapsed ? xtpPanePinPushed : 0);
return m_bShowPinButton;
}
if (pButton->GetID() == XTP_IDS_DOCKINGPANE_MENU)
{
CXTPDockingPane* pSelectedPane = GetSelectedPane();
return pSelectedPane && (pSelectedPane->GetOptions() & xtpPaneHasMenuButton);
}
return TRUE;
}
void CXTPDockingPaneMiniWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (IsThemed())
{
CPoint ptClick(point);
CXTPDrawHelpers::ScreenToWindow(this, &ptClick);
for (int i = 0; i < m_pCaptionButtons->GetSize(); i++)
{
CXTPDockingPaneCaptionButton* pButton = m_pCaptionButtons->GetAt(i);
if (pButton->PtInRect(ptClick))
{
if (!pButton->IsEnabled())
return;
if (OnCaptionButtonDown(pButton))
return;
if (pButton->Click(this, ptClick, FALSE))
{
OnCaptionButtonClick(pButton);
}
return;
}
}
}
if (nHitTest == HTCAPTION)
{
// special activation for floating toolbars
ActivateTopParent();
BringWindowToTop();
CXTPDockingPaneContext* pContext = GetDockingPaneManager()->GetDockingContext();
pContext->Drag(m_pTopContainer, point);
return;
}
CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
}
void CXTPDockingPaneMiniWnd::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == TID_NCLEAVE)
{
CPoint pt;
::GetCursorPos (&pt);
CXTPWindowRect rcCaption(this);
rcCaption.bottom = rcCaption.top + GetPaintManager()->GetCaptionHeight() + 4;
if (!rcCaption.PtInRect(pt))
{
m_pCaptionButtons->CheckForMouseOver(CPoint(-1, -1));
KillTimer(TID_NCLEAVE);
}
}
if (nIDEvent == TID_SLIDEOUT && m_bSlideOut)
{
m_nSlideStep--;
if (m_nSlideStep > -1)
DoSlideStep();
else
{
m_bSlideOut = FALSE;
m_bExpanded = FALSE;
KillTimer(TID_SLIDEOUT);
OnAction(xtpPaneActionCollapsed);
}
}
if (nIDEvent == TID_CHECKACTIVE)
{
CPoint pt;
GetCursorPos(&pt);
CWnd* pFocus = GetFocus();
BOOL bActive = (pFocus->GetSafeHwnd() && (pFocus == this || IsChild(pFocus)));
if (!bActive && !m_bSlideOut && !CXTPWindowRect(this).PtInRect(pt) && ::GetCapture() == NULL)
{
if (--m_nDeactivationCount <= 0)
{
if (OnAction(xtpPaneActionCollapsing))
{
m_nDeactivationCount = 6;
return;
}
if (m_nSlideStep == m_nStepsCount)
{
m_nExpandedHeight = CXTPWindowRect(this).Height();
}
m_bSlideOut = TRUE;
SetTimer(TID_SLIDEOUT, CXTPDockingPaneAutoHideWnd::m_nAnimationInterval, NULL);
KillTimer(TID_CHECKACTIVE);
}
}
}
CMiniFrameWnd::OnTimer(nIDEvent);
}
void CXTPDockingPaneMiniWnd::OnThemedChanged()
{
if (!m_hWnd)
return;
ModifyStyle(IsThemed() ? WS_BORDER | WS_THICKFRAME: 0, IsThemed() ? 0 : WS_BORDER | WS_THICKFRAME, SWP_FRAMECHANGED);
if (!IsThemed() && m_bCollapsed)
{
OnPinButtonClick();
}
SetWindowPos(0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
if (m_bCollapsed && IsThemed())
{
DoSlideStep();
}
}
void CXTPDockingPaneMiniWnd::Expand()
{
if (m_bCollapsed && m_nSlideStep <= 0)
{
if (m_bSlideOut)
{
m_bSlideOut = FALSE;
m_bExpanded = FALSE;
KillTimer(TID_SLIDEOUT);
OnAction(xtpPaneActionCollapsed);
}
if (OnAction(xtpPaneActionExpanding))
return;
m_bExpanded = TRUE;
m_nSlideStep = m_nStepsCount = ResetStepsCount();
DoSlideStep(TRUE);
m_nDeactivationCount = 8;
SetTimer(TID_CHECKACTIVE, 100, NULL);
OnAction(xtpPaneActionExpanded);
}
}
void CXTPDockingPaneMiniWnd::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
CMiniFrameWnd::OnGetMinMaxInfo(lpMMI);
if (IsThemed())
{
lpMMI->ptMinTrackSize.x = 46;
}
GetMinMaxInfo(lpMMI);
}
void CXTPDockingPaneMiniWnd::GetMinMaxInfo(LPMINMAXINFO lpMMI) const
{
if (m_pTopContainer && ((!m_bCollapsed || m_bExpanded) && !m_bSlideOut))
{
CXTPWindowRect rcWindow(this);
CXTPClientRect rcClient(this);
CSize szBorder = rcWindow.Size() - rcClient.Size();
MINMAXINFO mInfo;
m_pTopContainer->GetMinMaxInfo(&mInfo);
lpMMI->ptMinTrackSize.x = max(lpMMI->ptMinTrackSize.x, mInfo.ptMinTrackSize.x + szBorder.cx);
lpMMI->ptMinTrackSize.y = max(lpMMI->ptMinTrackSize.y, mInfo.ptMinTrackSize.y + szBorder.cy);
lpMMI->ptMaxTrackSize.x = min(lpMMI->ptMaxTrackSize.x, mInfo.ptMaxTrackSize.x + szBorder.cx);
lpMMI->ptMaxTrackSize.y = min(lpMMI->ptMaxTrackSize.y, mInfo.ptMaxTrackSize.y + szBorder.cy);
}
}
BOOL CXTPDockingPaneMiniWnd::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);
}
INT_PTR CXTPDockingPaneMiniWnd::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
{
ASSERT_VALID(this);
ASSERT(::IsWindow(m_hWnd));
if (!IsThemed())
return -1;
CXTPWindowRect rcWindow(this);
CPoint ptTopLeft(rcWindow.TopLeft());
ScreenToClient(&ptTopLeft);
if (GetExStyle() & WS_EX_LAYOUTRTL)
ptTopLeft.x -= rcWindow.Width();
for (int i = 0; i < m_pCaptionButtons->GetSize(); i++)
{
CXTPDockingPaneCaptionButton* pButton = m_pCaptionButtons->GetAt(i);
CRect rc = pButton->GetRect();
rc.OffsetRect(ptTopLeft);
if (rc.PtInRect(point))
{
INT_PTR nHit = (INT_PTR)pButton->GetID();
CString strTip;
XTPResourceManager()->LoadString(&strTip, (UINT)nHit);
if (strTip.GetLength() == 0)
return -1;
CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, rc, nHit, strTip);
return nHit;
}
}
return -1;
}
void CXTPDockingPaneMiniWnd::DeletePane()
{
InternalRelease();
}
void CXTPDockingPaneMiniWnd::OnFinalRelease()
{
if (m_hWnd != NULL)
DestroyWindow();
CCmdTarget::OnFinalRelease();
}