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.
903 lines
22 KiB
C++
903 lines
22 KiB
C++
2 years ago
|
// XTPTaskPanelGroup.cpp : implementation of the CXTPTaskPanelGroup class.
|
||
|
//
|
||
|
// This file is a part of the XTREME TASKPANEL 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/XTPImageManager.h"
|
||
|
#include "Common/XTPPropExchange.h"
|
||
|
#include "Common/XTPSystemHelpers.h"
|
||
|
#include "Common/XTPColorManager.h"
|
||
|
|
||
|
#include "XTPTaskPanelDefines.h"
|
||
|
#include "XTPTaskPanelItem.h"
|
||
|
#include "XTPTaskPanelGroup.h"
|
||
|
#include "XTPTaskPanelGroupItem.h"
|
||
|
#include "XTPTaskPanelItems.h"
|
||
|
#include "XTPTaskPanel.h"
|
||
|
#include "XTPTaskPanelPaintManager.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPTaskPanelGroup
|
||
|
|
||
|
IMPLEMENT_SERIAL(CXTPTaskPanelGroup, CXTPTaskPanelItem, VERSIONABLE_SCHEMA | _XTP_SCHEMA_CURRENT)
|
||
|
|
||
|
CXTPTaskPanelGroup::CXTPTaskPanelGroup(CXTPTaskPanel* pPanel)
|
||
|
{
|
||
|
m_typeItem = xtpTaskItemTypeGroup;
|
||
|
|
||
|
m_bSpecial = FALSE;
|
||
|
|
||
|
m_rcMarginsOuter = CXTPTaskPanelPaintManager::rectDefault;
|
||
|
m_rcMarginsInner = CXTPTaskPanelPaintManager::rectDefault;
|
||
|
|
||
|
|
||
|
m_rcGroupTarget.SetRectEmpty();
|
||
|
m_rcGroupCurrent.SetRectEmpty();
|
||
|
|
||
|
m_pItems = new CXTPTaskPanelGroupItems(pPanel);
|
||
|
m_pItems->m_pOwner = this;
|
||
|
|
||
|
m_nCaptionHeight = 0;
|
||
|
m_nExpandedClientHeight = 0;
|
||
|
m_bCaptionVisible = TRUE;
|
||
|
|
||
|
m_bExpandable = TRUE;
|
||
|
m_bExpanded = TRUE;
|
||
|
m_bExpanding = FALSE;
|
||
|
m_itemLayout = xtpTaskItemLayoutDefault;
|
||
|
|
||
|
m_nScrollOffset = 0;
|
||
|
m_nItemsInRow = 1;
|
||
|
|
||
|
m_szItemIcon = CSize(0);
|
||
|
|
||
|
m_nMinClientHeight = 0;
|
||
|
|
||
|
m_nBackgroundImage = -1;
|
||
|
m_nBackgroundAlignemnt = DT_RIGHT | DT_BOTTOM;
|
||
|
|
||
|
EnableAutomation();
|
||
|
}
|
||
|
|
||
|
CXTPTaskPanelGroup::~CXTPTaskPanelGroup()
|
||
|
{
|
||
|
m_pItems->InternalRelease();
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::OnRemoved()
|
||
|
{
|
||
|
m_pItems->Clear(FALSE);
|
||
|
m_pItems->m_pPanel = NULL;
|
||
|
}
|
||
|
|
||
|
int CXTPTaskPanelGroup::GetMinimumClientHeight() const
|
||
|
{
|
||
|
return max(m_nMinClientHeight, GetTaskPanel()->GetMinimumGroupClientHeight());
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetMinimumClientHeight(int nMinClientHeight)
|
||
|
{
|
||
|
m_nMinClientHeight = nMinClientHeight;
|
||
|
}
|
||
|
|
||
|
|
||
|
CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::AddLinkItem(UINT nID, int nImage)
|
||
|
{
|
||
|
CXTPTaskPanel::CRepositionContext context(m_pPanel);
|
||
|
|
||
|
CXTPTaskPanelGroupItem* pItem = (CXTPTaskPanelGroupItem*)m_pItems->Add(new CXTPTaskPanelGroupItem(), nID);
|
||
|
pItem->SetIconIndex(nImage);
|
||
|
pItem->SetType(xtpTaskItemTypeLink);
|
||
|
|
||
|
return pItem;
|
||
|
}
|
||
|
CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::AddTextItem(LPCTSTR strText)
|
||
|
{
|
||
|
CXTPTaskPanel::CRepositionContext context(m_pPanel);
|
||
|
|
||
|
CXTPTaskPanelGroupItem* pItem = (CXTPTaskPanelGroupItem*)m_pItems->Add(new CXTPTaskPanelGroupItem(), 0);
|
||
|
pItem->SetCaption(strText);
|
||
|
|
||
|
return pItem;
|
||
|
}
|
||
|
|
||
|
CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::AddControlItem(HWND hWnd)
|
||
|
{
|
||
|
CXTPTaskPanel::CRepositionContext context(m_pPanel);
|
||
|
|
||
|
CXTPTaskPanelGroupItem* pItem = (CXTPTaskPanelGroupItem*)m_pItems->Add(new CXTPTaskPanelGroupItem(), 0);
|
||
|
pItem->SetControlHandle(hWnd);
|
||
|
|
||
|
return pItem;
|
||
|
}
|
||
|
|
||
|
|
||
|
CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::GetAt(int nIndex) const
|
||
|
{
|
||
|
return (CXTPTaskPanelGroupItem*)m_pItems->GetAt(nIndex);
|
||
|
}
|
||
|
CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::FindItem(int nID) const
|
||
|
{
|
||
|
return (CXTPTaskPanelGroupItem*)m_pItems->Find(nID);
|
||
|
}
|
||
|
|
||
|
BOOL CXTPTaskPanelGroup::IsDirty() const
|
||
|
{
|
||
|
return (m_rcGroupCurrent != m_rcGroupTarget) && IsVisible();
|
||
|
}
|
||
|
|
||
|
int CXTPTaskPanelGroup::CalcInsideHeight()
|
||
|
{
|
||
|
CRect rc;
|
||
|
m_pPanel->GetClientRect(&rc);
|
||
|
int nInsideHeight = rc.Height();
|
||
|
|
||
|
CXTPTaskPanelPaintManager* pPaintManager = GetPaintManager();
|
||
|
|
||
|
int nGroupSpacing = pPaintManager->GetGroupSpacing(m_pPanel);
|
||
|
CRect rcMargins = pPaintManager->GetControlMargins(m_pPanel);
|
||
|
|
||
|
int nGroupCount = m_pPanel->GetGroupCount();
|
||
|
int nVisibleCount = 0;
|
||
|
|
||
|
for (int i = 0; i < nGroupCount; i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroup* pGroup = m_pPanel->GetAt(i);
|
||
|
if (!pGroup->IsVisible())
|
||
|
continue;
|
||
|
|
||
|
nVisibleCount++;
|
||
|
|
||
|
CRect rcMarginsOuter = pPaintManager->GetGroupOuterMargins(pGroup);
|
||
|
|
||
|
nInsideHeight -= pGroup->m_nCaptionHeight + rcMarginsOuter.top + rcMarginsOuter.bottom;
|
||
|
if (pGroup->IsExpanded() && pGroup != m_pPanel->GetActiveGroup())
|
||
|
nInsideHeight -= pGroup->m_nExpandedClientHeight;
|
||
|
}
|
||
|
nInsideHeight -= nVisibleCount > 0 ? nGroupSpacing * (nVisibleCount - 1) : 0;
|
||
|
nInsideHeight -= rcMargins.top + rcMargins.bottom;
|
||
|
|
||
|
return nInsideHeight;
|
||
|
}
|
||
|
|
||
|
CSize CXTPTaskPanelGroup::GetItemIconSize() const
|
||
|
{
|
||
|
return m_szItemIcon == CSize(0) ? GetTaskPanel()->GetItemIconSize() : m_szItemIcon;
|
||
|
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetIconSize(CSize szItemIcon)
|
||
|
{
|
||
|
m_szItemIcon = szItemIcon;
|
||
|
GetTaskPanel()->Reposition();
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPTaskPanelGroup::OnCalcClientHeight(CDC* pDC, CRect rc)
|
||
|
{
|
||
|
CXTPTaskPanelPaintManager* pPaintManager = GetPaintManager();
|
||
|
CRect rcMarginsOuter = pPaintManager->GetGroupOuterMargins(this);
|
||
|
CRect rcMarginsInner = pPaintManager->GetGroupInnerMargins(this);
|
||
|
|
||
|
rc.DeflateRect(rcMarginsOuter);
|
||
|
CRect rcItems(rc);
|
||
|
|
||
|
rcItems.DeflateRect(rcMarginsInner);
|
||
|
m_nItemsInRow = 1;
|
||
|
int nItemCount = GetItemCount();
|
||
|
|
||
|
if (GetItemLayout() == xtpTaskItemLayoutImages)
|
||
|
{
|
||
|
CSize szIcon = GetItemIconSize();
|
||
|
CRect rcInnerMargins(pPaintManager->m_rcImageLayoutIconPadding);
|
||
|
CSize szButton(szIcon.cx + rcInnerMargins.right + rcInnerMargins.left,
|
||
|
szIcon.cy + rcInnerMargins.top + rcInnerMargins.bottom);
|
||
|
|
||
|
int nRowIcons = max(1, rcItems.Width() / szButton.cx), x = 0, y = 0;
|
||
|
BOOL bWrap = FALSE;
|
||
|
|
||
|
for (int i = 0; i < nItemCount; i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(i);
|
||
|
|
||
|
if (!pItem->IsVisible())
|
||
|
continue;
|
||
|
|
||
|
if (bWrap)
|
||
|
{
|
||
|
x = 0;
|
||
|
y++;
|
||
|
bWrap = FALSE;
|
||
|
}
|
||
|
|
||
|
CRect rcItem(CPoint(rcItems.left + x * szButton.cx, rcItems.top + y * szButton.cy), szButton);
|
||
|
pItem->OnReposition(rcItem);
|
||
|
|
||
|
if (++x == nRowIcons)
|
||
|
bWrap = TRUE;
|
||
|
}
|
||
|
rcItems.bottom = rcItems.top + rcMarginsInner.bottom + szButton.cy * (y + 1);
|
||
|
m_nItemsInRow = nRowIcons;
|
||
|
|
||
|
SetOffsetItem(m_nScrollOffset);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
BOOL bMultiColumn = m_pPanel->IsMultiColumn();
|
||
|
int nRowHeight = 0;
|
||
|
CRect rcItemOuterMargins(0, 0, 0, 0);
|
||
|
int nColumnWidth = m_pPanel->GetColumnWidth();
|
||
|
ASSERT(nColumnWidth > 0);
|
||
|
int x = 0;
|
||
|
BOOL bWrap = FALSE;
|
||
|
|
||
|
int nRowIcons = max(1, rcItems.Width() / nColumnWidth);
|
||
|
|
||
|
for (int i = 0; i < nItemCount; i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(i);
|
||
|
|
||
|
if (!pItem->IsVisible())
|
||
|
continue;
|
||
|
|
||
|
if (bMultiColumn)
|
||
|
{
|
||
|
if (bWrap)
|
||
|
{
|
||
|
rcItems.top += nRowHeight;
|
||
|
|
||
|
nRowHeight = 0;
|
||
|
x = 0;
|
||
|
bWrap = FALSE;
|
||
|
}
|
||
|
|
||
|
CRect rcItem = pItem->OnReposition(CRect(rcItems.left + x * nColumnWidth, rcItems.top, rcItems.left + (x + 1) * nColumnWidth, rcItems.bottom));
|
||
|
|
||
|
|
||
|
rcItemOuterMargins = pPaintManager->GetItemOuterMargins(pItem);
|
||
|
|
||
|
nRowHeight = max(nRowHeight, rcItem.Height() + rcItemOuterMargins.bottom);
|
||
|
|
||
|
if (++x == nRowIcons)
|
||
|
bWrap = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CRect rcItem = pItem->OnReposition(rcItems);
|
||
|
rcItems.top = rcItem.bottom + pPaintManager->GetItemOuterMargins(pItem).bottom;
|
||
|
}
|
||
|
}
|
||
|
if (bMultiColumn)
|
||
|
{
|
||
|
rcItems.top += nRowHeight;
|
||
|
m_nItemsInRow = nRowIcons;
|
||
|
}
|
||
|
rcItems.bottom = rcItems.top + rcMarginsInner.bottom;
|
||
|
}
|
||
|
|
||
|
int nMinClientHeight = GetMinimumClientHeight();
|
||
|
if (rcItems.bottom - rc.top < nMinClientHeight)
|
||
|
rcItems.bottom = rc.top + nMinClientHeight;
|
||
|
|
||
|
m_nExpandedClientHeight = rcItems.bottom - rc.top;
|
||
|
|
||
|
m_nCaptionHeight = pPaintManager->DrawGroupCaption(pDC, this, FALSE);
|
||
|
}
|
||
|
|
||
|
CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::GetNextVisibleItem(int nIndex, int nDirection) const
|
||
|
{
|
||
|
return GetAt(m_pItems->GetNextVisibleIndex(nIndex, nDirection));
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::RepositionScrollOffset()
|
||
|
{
|
||
|
int nItemCount = GetItemCount();
|
||
|
int nLastVisibleItem = m_pItems->GetNextVisibleIndex(nItemCount, -1);
|
||
|
|
||
|
int nScrollOffset = min(GetOffsetItem(), nLastVisibleItem);
|
||
|
|
||
|
if (nScrollOffset > 0)
|
||
|
{
|
||
|
CRect rcItem(GetAt(nLastVisibleItem)->GetItemRect());
|
||
|
|
||
|
int nTopMargin = GetPaintManager()->GetGroupInnerMargins(this).top;
|
||
|
|
||
|
while ((nScrollOffset > 0) && ((rcItem.bottom - GetAt(nScrollOffset - 1)->GetItemRect().top + nTopMargin
|
||
|
< m_nExpandedClientHeight) || !GetAt(nScrollOffset - 1)->IsVisible()))
|
||
|
{
|
||
|
nScrollOffset--;
|
||
|
}
|
||
|
}
|
||
|
SetOffsetItem(nScrollOffset, FALSE);
|
||
|
|
||
|
for (int i = 0; i < nItemCount; i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(i);
|
||
|
|
||
|
if (pItem->IsItemFocused() || (pItem->IsItemSelected() && GetTaskPanel()->m_bSelectItemOnFocus))
|
||
|
{
|
||
|
EnsureVisible(pItem, FALSE);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::RepositionAutoHeightControls(int nHeightOffset)
|
||
|
{
|
||
|
if (GetItemLayout() == xtpTaskItemLayoutImages)
|
||
|
return;
|
||
|
|
||
|
int nCount = 0, i, nTotalHeight = 0, nItemCount = GetItemCount(), nOffset = 0;
|
||
|
|
||
|
for (i = 0; i < nItemCount; i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(i);
|
||
|
if (pItem->IsAutoHeight() && pItem->IsVisible())
|
||
|
{
|
||
|
nCount++;
|
||
|
nTotalHeight += max(1, pItem->GetSize().cy);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (nCount == 0)
|
||
|
return;
|
||
|
|
||
|
for (i = 0; i < nItemCount; i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(i);
|
||
|
pItem->m_rcItem.OffsetRect(0, nOffset);
|
||
|
|
||
|
if (pItem->IsAutoHeight() && pItem->IsVisible())
|
||
|
{
|
||
|
int nItemHeight = max(1, pItem->GetSize().cy);
|
||
|
int nItemHeightOffset = nCount > 1 ? (int)(nItemHeight* nHeightOffset / nTotalHeight) : nHeightOffset;
|
||
|
|
||
|
nCount--;
|
||
|
nTotalHeight -= nItemHeight;
|
||
|
nHeightOffset -= nItemHeightOffset;
|
||
|
|
||
|
pItem->m_rcItem.bottom += nItemHeightOffset;
|
||
|
nOffset += nItemHeightOffset;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
CRect CXTPTaskPanelGroup::OnReposition(CRect rc, BOOL bRecalcOnly)
|
||
|
{
|
||
|
if (m_pPanel->IsExplorerBehaviour())
|
||
|
SetOffsetItem(0, FALSE);
|
||
|
|
||
|
CXTPTaskPanelPaintManager* pPaintManager = GetPaintManager();
|
||
|
CRect rcMarginsOuter = pPaintManager->GetGroupOuterMargins(this);
|
||
|
|
||
|
rc.DeflateRect(rcMarginsOuter);
|
||
|
|
||
|
m_rcGroupTarget = rc;
|
||
|
|
||
|
if (!m_pPanel->IsExplorerBehaviour() && (m_pPanel->GetActiveGroup() == this || IsExpanding()))
|
||
|
{
|
||
|
CRect rcMarginsInner = pPaintManager->GetGroupInnerMargins(this);
|
||
|
int nInsideHeight = CalcInsideHeight();
|
||
|
int nButtonHeight = max(32, GetItemIconSize().cy + rcMarginsInner.bottom);
|
||
|
|
||
|
int nExpandedClientHeight = max(nButtonHeight + rcMarginsInner.top + 2, nInsideHeight);
|
||
|
|
||
|
int nMinClientHeight = GetMinimumClientHeight();
|
||
|
nExpandedClientHeight = max(nMinClientHeight, nExpandedClientHeight);
|
||
|
|
||
|
if (nExpandedClientHeight > m_nExpandedClientHeight)
|
||
|
{
|
||
|
RepositionAutoHeightControls(nExpandedClientHeight - m_nExpandedClientHeight);
|
||
|
}
|
||
|
|
||
|
m_nExpandedClientHeight = nExpandedClientHeight;
|
||
|
RepositionScrollOffset();
|
||
|
}
|
||
|
|
||
|
int nClientHeight = IsExpanded() ? m_nExpandedClientHeight : 0;
|
||
|
|
||
|
m_rcGroupTarget.bottom = m_rcGroupTarget.top + m_nCaptionHeight + nClientHeight;
|
||
|
|
||
|
m_rcGroupCurrent.left = m_rcGroupTarget.left;
|
||
|
m_rcGroupCurrent.right = m_rcGroupTarget.right;
|
||
|
|
||
|
if (!bRecalcOnly || !m_pPanel->m_bAnimation) OnAnimate(0);
|
||
|
else if (!IsDirty()) OnAnimate(0);
|
||
|
|
||
|
|
||
|
return m_rcGroupTarget;
|
||
|
}
|
||
|
|
||
|
#define MOVETO(A, B, Step) if (A != B) A += max(1, abs(A - B)/Step) * (A > B ? -1 : 1);
|
||
|
|
||
|
void CXTPTaskPanelGroup::OnAnimate(int nStep)
|
||
|
{
|
||
|
if (nStep < 1)
|
||
|
{
|
||
|
m_rcGroupCurrent = m_rcGroupTarget;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MOVETO(m_rcGroupCurrent.top, m_rcGroupTarget.top, nStep);
|
||
|
MOVETO(m_rcGroupCurrent.bottom, m_rcGroupTarget.bottom, nStep);
|
||
|
}
|
||
|
|
||
|
if (!IsDirty() && m_bExpanding)
|
||
|
{
|
||
|
m_bExpanding = FALSE;
|
||
|
m_pPanel->NotifyOwner(XTP_TPN_GROUPEXPANDED, (LPARAM)this);
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < GetItemCount(); i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(i);
|
||
|
|
||
|
pItem->OnAnimate(nStep);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::OnPaint(CDC* pDC)
|
||
|
{
|
||
|
GetPaintManager()->DrawGroupCaption(pDC, this, TRUE);
|
||
|
|
||
|
GetPaintManager()->DrawGroupClient(pDC, this);
|
||
|
}
|
||
|
|
||
|
CRect CXTPTaskPanelGroup::GetCaptionRect() const
|
||
|
{
|
||
|
int nCaptionRight = m_rcGroupCurrent.right;
|
||
|
if (m_pPanel->GetScrollButton(TRUE)->pGroupCaption == this)
|
||
|
nCaptionRight = m_pPanel->GetScrollButton(TRUE)->rcButton.left - GetPaintManager()->GetGroupSpacing(m_pPanel) - 1;
|
||
|
if (m_pPanel->GetScrollButton(FALSE)->pGroupCaption == this)
|
||
|
nCaptionRight = m_pPanel->GetScrollButton(FALSE)->rcButton.left - GetPaintManager()->GetGroupSpacing(m_pPanel) - 1;
|
||
|
|
||
|
return CRect(m_rcGroupCurrent.left, m_rcGroupCurrent.top, nCaptionRight, m_rcGroupCurrent.top + m_nCaptionHeight);
|
||
|
}
|
||
|
|
||
|
CRect CXTPTaskPanelGroup::GetTargetCaptionRect() const
|
||
|
{
|
||
|
int nGroupSpacing = GetPaintManager()->GetGroupSpacing(m_pPanel);
|
||
|
|
||
|
int nCaptionRight = m_rcGroupTarget.right;
|
||
|
|
||
|
if (m_pPanel->GetScrollButton(TRUE)->pGroupCaption == this)
|
||
|
{
|
||
|
nCaptionRight = m_pPanel->GetScrollButton(TRUE)->rcButton.left - nGroupSpacing - 1;
|
||
|
}
|
||
|
|
||
|
if (m_pPanel->GetScrollButton(FALSE)->pGroupCaption == this)
|
||
|
{
|
||
|
nCaptionRight = m_pPanel->GetScrollButton(FALSE)->rcButton.left - nGroupSpacing - 1;
|
||
|
}
|
||
|
|
||
|
return CRect(m_rcGroupTarget.left, m_rcGroupTarget.top, nCaptionRight, m_rcGroupTarget.top + m_nCaptionHeight);
|
||
|
}
|
||
|
|
||
|
CRect CXTPTaskPanelGroup::GetClientRect() const
|
||
|
{
|
||
|
return CRect(m_rcGroupCurrent.left, m_rcGroupCurrent.top + m_nCaptionHeight, m_rcGroupCurrent.right, m_rcGroupCurrent.bottom);
|
||
|
}
|
||
|
|
||
|
CRect CXTPTaskPanelGroup::GetTargetClientRect() const
|
||
|
{
|
||
|
return CRect(m_rcGroupTarget.left, m_rcGroupTarget.top + m_nCaptionHeight, m_rcGroupTarget.right, m_rcGroupTarget.bottom);
|
||
|
}
|
||
|
|
||
|
BOOL CXTPTaskPanelGroup::IsAcceptFocus() const
|
||
|
{
|
||
|
return CXTPTaskPanelItem::IsAcceptFocus() && IsExpandable();
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetSpecialGroup(BOOL bSpecial)
|
||
|
{
|
||
|
m_bSpecial = bSpecial;
|
||
|
RedrawPanel();
|
||
|
}
|
||
|
BOOL CXTPTaskPanelGroup::IsSpecialGroup() const
|
||
|
{
|
||
|
return m_bSpecial;
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetExpandable(BOOL bExpandable)
|
||
|
{
|
||
|
m_bExpandable = bExpandable;
|
||
|
|
||
|
RedrawPanel();
|
||
|
}
|
||
|
BOOL CXTPTaskPanelGroup::IsExpandable() const
|
||
|
{
|
||
|
return m_bExpandable && m_pPanel->m_bExpandable && m_bEnabled;
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetExpanded(BOOL bExpanded)
|
||
|
{
|
||
|
if (m_pPanel)
|
||
|
m_pPanel->ExpandGroup(this, bExpanded);
|
||
|
}
|
||
|
|
||
|
BOOL CXTPTaskPanelGroup::IsExpanded() const
|
||
|
{
|
||
|
return m_pPanel ? m_pPanel->IsGroupExpanded(this) : FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPTaskPanelGroup::IsExpanding() const
|
||
|
{
|
||
|
return m_bExpanding;
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::ShowCaption(BOOL bShow)
|
||
|
{
|
||
|
if (m_bCaptionVisible != bShow)
|
||
|
{
|
||
|
m_bCaptionVisible = bShow;
|
||
|
RepositionPanel();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL CXTPTaskPanelGroup::IsCaptionVisible() const
|
||
|
{
|
||
|
return m_bCaptionVisible;
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetClientBitmap(UINT nID, COLORREF clrTransparent, int nBackgroundAlignemnt)
|
||
|
{
|
||
|
UINT nIDCommands = {nID};
|
||
|
CXTPImageManager* pImageManager = m_pPanel->GetImageManager();
|
||
|
|
||
|
COLORREF clrOldMask = pImageManager->SetMaskColor(clrTransparent);
|
||
|
pImageManager->SetIcons(nID, &nIDCommands, 1, CSize(0, 0), xtpImageNormal);
|
||
|
pImageManager->SetMaskColor(clrOldMask);
|
||
|
|
||
|
m_nBackgroundImage = nID;
|
||
|
m_nBackgroundAlignemnt = nBackgroundAlignemnt;
|
||
|
|
||
|
}
|
||
|
void CXTPTaskPanelGroup::OnFillClient(CDC* pDC, CRect rc)
|
||
|
{
|
||
|
if (m_nBackgroundImage != -1)
|
||
|
{
|
||
|
CXTPImageManagerIcon* pIcon = m_pPanel->GetImageManager()->GetImage(m_nBackgroundImage, ICON_BIG);
|
||
|
|
||
|
if (!pIcon)
|
||
|
return;
|
||
|
|
||
|
CPoint pt(rc.left, rc.top);
|
||
|
|
||
|
if (m_nBackgroundAlignemnt & DT_RIGHT)
|
||
|
pt.x = rc.right - pIcon->GetWidth();
|
||
|
else if (m_nBackgroundAlignemnt & DT_CENTER)
|
||
|
pt.x = rc.CenterPoint().x - pIcon->GetWidth() / 2;
|
||
|
|
||
|
if (m_nBackgroundAlignemnt & DT_BOTTOM)
|
||
|
pt.y = rc.bottom - pIcon->GetHeight();
|
||
|
else if (m_nBackgroundAlignemnt & DT_VCENTER)
|
||
|
pt.y = rc.CenterPoint().y - pIcon->GetHeight() / 2;
|
||
|
|
||
|
pIcon->Draw(pDC, pt);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CRect CXTPTaskPanelGroup::GetHitTestRect() const
|
||
|
{
|
||
|
if (!m_pPanel)
|
||
|
return CRect(0, 0, 0, 0);
|
||
|
|
||
|
CRect rc = GetCaptionRect();
|
||
|
rc.OffsetRect(0, -m_pPanel->GetScrollOffset());
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
CRect CXTPTaskPanelGroup::GetInvalidateRect() const
|
||
|
{
|
||
|
if (!m_pPanel)
|
||
|
return CRect(0, 0, 0, 0);
|
||
|
|
||
|
CRect rc = m_rcGroupCurrent;
|
||
|
rc.OffsetRect(0, -m_pPanel->GetScrollOffset());
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::HitTest(CPoint pt, CRect* lpRect) const
|
||
|
{
|
||
|
if (!IsExpanded())
|
||
|
return NULL;
|
||
|
|
||
|
int nOffset = m_pPanel->GetScrollOffset() - m_nCaptionHeight - m_rcGroupCurrent.top + GetScrollOffsetPos();
|
||
|
pt.y += nOffset;
|
||
|
|
||
|
for (int i = 0; i < GetItemCount(); i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(i);
|
||
|
CRect rcItem = pItem->GetItemRect();
|
||
|
|
||
|
if (rcItem.PtInRect(pt) && pItem->IsVisible())
|
||
|
{
|
||
|
if (lpRect)
|
||
|
{
|
||
|
rcItem.OffsetRect(0, -nOffset);
|
||
|
*lpRect = rcItem;
|
||
|
}
|
||
|
return pItem;
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
XTPTaskPanelItemLayout CXTPTaskPanelGroup::GetItemLayout() const
|
||
|
{
|
||
|
if (m_itemLayout != xtpTaskItemLayoutDefault)
|
||
|
return m_itemLayout;
|
||
|
|
||
|
return m_pPanel->GetItemLayout();
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetItemLayout(XTPTaskPanelItemLayout itemLayout)
|
||
|
{
|
||
|
if (itemLayout != m_itemLayout)
|
||
|
{
|
||
|
m_itemLayout = itemLayout;
|
||
|
RepositionPanel();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetSelectedItem(CXTPTaskPanelGroupItem* pSelectedItem)
|
||
|
{
|
||
|
int nCount = GetItemCount();
|
||
|
|
||
|
for (int i = 0; i < nCount; i++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(i);
|
||
|
pItem->SetItemSelected(pSelectedItem == pItem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL CXTPTaskPanelGroup::IsChildItemDragOver() const
|
||
|
{
|
||
|
return m_pPanel && m_pPanel->m_pItemDragOver &&
|
||
|
m_pPanel->m_pItemDragOver->GetParentItems() == m_pItems;
|
||
|
}
|
||
|
|
||
|
int CXTPTaskPanelGroup::GetItemCount() const
|
||
|
{
|
||
|
return m_pItems->GetCount();
|
||
|
}
|
||
|
|
||
|
BOOL CXTPTaskPanelGroup::IsScrollButtonEnabled(BOOL bScrollButtonUp) const
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pLastVisibleItem = (CXTPTaskPanelGroupItem*)m_pItems->GetLastVisibleItem();
|
||
|
|
||
|
if (pLastVisibleItem == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
if (bScrollButtonUp)
|
||
|
return m_nScrollOffset != 0;
|
||
|
|
||
|
CRect rcItem(pLastVisibleItem->GetItemRect());
|
||
|
|
||
|
return rcItem.bottom - GetScrollOffsetPos() > m_rcGroupTarget.Height() - m_nCaptionHeight;
|
||
|
}
|
||
|
|
||
|
int CXTPTaskPanelGroup::GetOffsetItem() const
|
||
|
{
|
||
|
if (m_nScrollOffset == 0)
|
||
|
return 0;
|
||
|
|
||
|
if (m_nScrollOffset < GetItemCount())
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItem = GetAt(m_nScrollOffset);
|
||
|
|
||
|
if (pItem->IsVisible())
|
||
|
return m_nScrollOffset;
|
||
|
|
||
|
int nScrollOffset = m_pItems->GetNextVisibleIndex(m_nScrollOffset, +1);
|
||
|
|
||
|
if (nScrollOffset != -1)
|
||
|
return nScrollOffset;
|
||
|
|
||
|
nScrollOffset = m_pItems->GetNextVisibleIndex(m_nScrollOffset, -1);
|
||
|
if (nScrollOffset != -1)
|
||
|
return nScrollOffset;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int CXTPTaskPanelGroup::GetScrollOffsetPos() const
|
||
|
{
|
||
|
int nScrollOffset = GetOffsetItem();
|
||
|
|
||
|
if (nScrollOffset > 0 && nScrollOffset < GetItemCount())
|
||
|
{
|
||
|
return GetAt(nScrollOffset)->GetItemRect().top - GetPaintManager()->GetGroupInnerMargins(this).top;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::SetOffsetItem(int nScrollOffset, BOOL bUpdateScrollButtons /*= TRUE*/)
|
||
|
{
|
||
|
nScrollOffset = nScrollOffset - (nScrollOffset % m_nItemsInRow);
|
||
|
|
||
|
if (nScrollOffset > GetItemCount() - 1)
|
||
|
nScrollOffset = GetItemCount() - 1;
|
||
|
|
||
|
if (nScrollOffset < 0)
|
||
|
nScrollOffset = 0;
|
||
|
|
||
|
if (m_nScrollOffset != nScrollOffset)
|
||
|
{
|
||
|
m_nScrollOffset = nScrollOffset;
|
||
|
|
||
|
if (bUpdateScrollButtons)
|
||
|
{
|
||
|
OnAnimate(0);
|
||
|
m_pPanel->UpdateScrollButtons();
|
||
|
}
|
||
|
RedrawPanel(FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::Scroll(int nDelta)
|
||
|
{
|
||
|
SetOffsetItem(m_pItems->GetNextVisibleIndex(GetOffsetItem(), nDelta));
|
||
|
}
|
||
|
|
||
|
BOOL CXTPTaskPanelGroup::IsItemVisible(CXTPTaskPanelGroupItem* pItem, BOOL bAllowPart) const
|
||
|
{
|
||
|
if (!IsExpanded())
|
||
|
return FALSE;
|
||
|
|
||
|
if (!pItem || pItem->GetItemGroup() != this || !pItem->IsVisible())
|
||
|
return FALSE;
|
||
|
|
||
|
if (m_pPanel->IsExplorerBehaviour())
|
||
|
return TRUE;
|
||
|
|
||
|
int nIndex = pItem->GetIndex();
|
||
|
|
||
|
if (m_nScrollOffset > nIndex)
|
||
|
return FALSE;
|
||
|
|
||
|
CRect rcItem(pItem->GetItemRect());
|
||
|
if ((bAllowPart ? rcItem.top : rcItem.bottom) - GetScrollOffsetPos() > m_rcGroupTarget.Height() - m_nCaptionHeight)
|
||
|
return FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::EnsureVisible(CXTPTaskPanelGroupItem* pItem, BOOL bUpdateScrollButtons /*= TRUE*/)
|
||
|
{
|
||
|
if (m_pPanel->IsExplorerBehaviour() || GetItemCount() == 0 || !IsExpanded())
|
||
|
return;
|
||
|
|
||
|
if (!pItem || pItem->GetItemGroup() != this || !pItem->IsVisible())
|
||
|
return;
|
||
|
|
||
|
int nIndex = pItem->GetIndex();
|
||
|
|
||
|
if (m_nScrollOffset > nIndex)
|
||
|
{
|
||
|
SetOffsetItem(nIndex, bUpdateScrollButtons);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CRect rcItem(pItem->GetItemRect());
|
||
|
if (rcItem.bottom - GetScrollOffsetPos() > m_nExpandedClientHeight)
|
||
|
{
|
||
|
int nTopMargin = GetPaintManager()->GetGroupInnerMargins(this).top;
|
||
|
if (rcItem.top - GetScrollOffsetPos() <= nTopMargin)
|
||
|
return;
|
||
|
|
||
|
int nScrollOffset = m_nScrollOffset + 1;
|
||
|
for (; nScrollOffset <= nIndex; nScrollOffset++)
|
||
|
{
|
||
|
CXTPTaskPanelGroupItem* pItemScroll = GetAt(nScrollOffset);
|
||
|
if (!pItemScroll || !pItemScroll->IsVisible())
|
||
|
continue;
|
||
|
|
||
|
int nScrollOffsetPos = pItemScroll->GetItemRect().top - nTopMargin;
|
||
|
|
||
|
if (rcItem.bottom - nScrollOffsetPos <= m_nExpandedClientHeight)
|
||
|
break;
|
||
|
|
||
|
if (rcItem.top - nScrollOffsetPos <= nTopMargin)
|
||
|
break;
|
||
|
}
|
||
|
SetOffsetItem(nScrollOffset, bUpdateScrollButtons);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPTaskPanelGroup::DoPropExchange(CXTPPropExchange* pPX)
|
||
|
{
|
||
|
CXTPTaskPanelItem::DoPropExchange(pPX);
|
||
|
|
||
|
BOOL bExpanded = IsExpanded();
|
||
|
|
||
|
PX_Bool(pPX, _T("CaptionVisible"), m_bCaptionVisible, TRUE);
|
||
|
PX_Bool(pPX, _T("Expandable"), m_bExpandable, TRUE);
|
||
|
PX_Bool(pPX, _T("Expanded"), bExpanded, FALSE);
|
||
|
PX_Bool(pPX, _T("Special"), m_bSpecial, FALSE);
|
||
|
PX_Enum(pPX, _T("Layout"), m_itemLayout, xtpTaskItemLayoutDefault);
|
||
|
PX_Rect(pPX, _T("MarginsInner"), m_rcMarginsInner, CXTPTaskPanelPaintManager::rectDefault);
|
||
|
PX_Rect(pPX, _T("MarginsOuter"), m_rcMarginsOuter, CXTPTaskPanelPaintManager::rectDefault);
|
||
|
PX_Size(pPX, _T("IconSize"), m_szItemIcon, CSize(0));
|
||
|
|
||
|
if (pPX->IsLoading())
|
||
|
{
|
||
|
m_pItems->m_pPanel = m_pPanel;
|
||
|
SetExpanded(bExpanded);
|
||
|
}
|
||
|
|
||
|
CXTPPropExchangeSection secItems(pPX->GetSection(_T("Items")));
|
||
|
m_pItems->DoPropExchange(&secItems);
|
||
|
}
|
||
|
|
||
|
HRESULT CXTPTaskPanelGroup::GetAccessibleState(VARIANT varChild, VARIANT* pvarState)
|
||
|
{
|
||
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
CXTPTaskPanelItem::GetAccessibleState(varChild, pvarState);
|
||
|
|
||
|
if (IsExpanded())
|
||
|
pvarState->lVal |= STATE_SYSTEM_EXPANDED;
|
||
|
else
|
||
|
pvarState->lVal |= STATE_SYSTEM_COLLAPSED;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CXTPTaskPanelGroup::GetAccessibleDefaultAction(VARIANT varChild, BSTR* pszDefaultAction)
|
||
|
{
|
||
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
*pszDefaultAction = SysAllocString(L"Expand");
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CXTPTaskPanelGroup::AccessibleDoDefaultAction(VARIANT varChild)
|
||
|
{
|
||
|
SAFE_MANAGE_STATE(m_pModuleState);
|
||
|
|
||
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
SetExpanded(!IsExpanded());
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CXTPTaskPanelGroup message handlers
|
||
|
|
||
|
|