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++
1175 lines
26 KiB
C++
// 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();
|
|
}
|
|
|
|
|