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.

630 lines
14 KiB
C++

// XTPRibbonTab.cpp: implementation of the CXTPRibbonTab class.
//
// This file is a part of the XTREME RIBBON 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/XTPDrawHelpers.h"
#include "Common/XTPPropExchange.h"
#include "Common/XTPColorManager.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPHookManager.h"
#include "TabManager/XTPTabManager.h"
#include "TabManager/XTPTabPaintManager.h"
#include "CommandBars/XTPCommandBarsDefines.h"
#include "CommandBars/XTPCommandBars.h"
#include "CommandBars/XTPCommandBar.h"
#include "CommandBars/XTPControls.h"
#include "CommandBars/XTPToolBar.h"
#include "CommandBars/XTPMenuBar.h"
#include "CommandBars/XTPPopupBar.h"
#include "CommandBars/XTPMouseManager.h"
#include "CommandBars/XTPControl.h"
#include "CommandBars/XTPControlButton.h"
#include "CommandBars/XTPControlPopup.h"
#include "XTPRibbonControlTab.h"
#include "XTPRibbonPopups.h"
#include "XTPRibbonBar.h"
#include "XTPRibbonTab.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
IMPLEMENT_XTP_CONTROL(CXTPRibbonControlTab, CXTPControl)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXTPRibbonControlTab::CXTPRibbonControlTab()
{
m_bAllowReorder = FALSE;
m_bFocused = FALSE;
m_bTemporary = TRUE;
SetFlags(xtpFlagNoMovable);
}
CXTPRibbonControlTab::~CXTPRibbonControlTab()
{
}
CXTPRibbonTab* CXTPRibbonControlTab::FindTab(int nID) const
{
for (int i = 0; i < GetItemCount(); i++)
{
CXTPRibbonTab* pTab = (CXTPRibbonTab*)GetItem(i);
if (pTab->GetID() == nID)
return pTab;
}
return NULL;
}
CXTPRibbonTab* CXTPRibbonControlTab::GetTab(int nIndex) const
{
return (CXTPRibbonTab*)GetItem(nIndex);
}
void CXTPRibbonControlTab::Reposition()
{
if (!m_pParent->GetSafeHwnd())
return;
m_pParent->OnRecalcLayout();
}
BOOL CXTPRibbonControlTab::IsMouseLocked() const
{
return GetRibbonBar()->GetCommandBars()->GetMouseManager()->IsMouseLocked();
}
CXTPTabPaintManager* CXTPRibbonControlTab::GetPaintManager() const
{
return GetRibbonBar()->GetTabPaintManager();
}
void CXTPRibbonControlTab::ShowPopupBar(BOOL bKeyboard)
{
if (!GetSelectedItem())
return;
CXTPRibbonBar* pRibbonBar = GetRibbonBar();
if (!pRibbonBar->IsRibbonMinimized())
return;
if (pRibbonBar->m_nPopuped == m_nIndex)
{
pRibbonBar->m_nPopuped = -1;
if (m_pCommandBar) m_pCommandBar->SetTrackingMode(FALSE);
}
pRibbonBar->SetTrackingMode(TRUE, FALSE);
pRibbonBar->SetPopuped(m_nIndex, bKeyboard);
}
void CXTPRibbonControlTab::SetEnabled(BOOL /*bEnabled*/)
{
}
CString CXTPRibbonControlTab::GetItemTooltip(const CXTPTabManagerItem* pItem) const
{
CString strToolTip = CXTPTabManager::GetItemTooltip(pItem);
if (!strToolTip.IsEmpty())
return strToolTip;
return pItem->GetCaption();
}
void CXTPRibbonControlTab::OnItemClick(CXTPTabManagerItem* pItem)
{
CXTPRibbonBar* pRibbonBar = GetRibbonBar();
if (pRibbonBar->IsCustomizable() && pRibbonBar->IsCustomizeMode())
{
CXTPRibbonTab* pTab = (CXTPRibbonTab*)pItem;
pRibbonBar->GetCommandBars()->SetDragControl(pTab);
}
CXTPTabManager::OnItemClick(pItem);
}
void CXTPRibbonControlTab::SetSelectedItem(CXTPTabManagerItem* pItem)
{
if (!m_pParent->GetSafeHwnd())
{
CXTPTabManager::SetSelectedItem(pItem);
return;
}
if (!IsFocused() && pItem && !GetRibbonBar()->IsRibbonMinimized())
m_pParent->GetCommandBars()->ClosePopups();
if (m_pSelected == pItem)
return;
if (m_pParent->GetCommandBars()->m_keyboardTips.nLevel > 1)
m_pParent->GetCommandBars()->HideKeyboardTips();
CXTPRibbonTab* pTab = (CXTPRibbonTab*)pItem;
CXTPRibbonBar* pRibbonBar = GetRibbonBar();
if (pRibbonBar->OnTabChanging(pTab))
return;
pRibbonBar->LockRedraw();
pRibbonBar->RebuildControls(pTab);
CXTPTabManager::SetSelectedItem(pTab);
pRibbonBar->OnIdleUpdateCmdUI(0, 0);
pRibbonBar->UnlockRedraw();
pRibbonBar->OnTabChanged(pTab);
NotifySite(CBN_XTP_EXECUTE);
if (pItem)
{
AccessibleNotifyWinEvent(EVENT_OBJECT_FOCUS , GetParent()->GetSafeHwnd(), GetID(), pItem->GetIndex() + 1);
}
}
void CXTPRibbonControlTab::AdjustExcludeRect(CRect& rc, BOOL /*bVertical*/)
{
rc.bottom--;
}
BOOL CXTPRibbonControlTab::DrawIcon(CDC* pDC, CPoint pt, CXTPTabManagerItem* pItem, BOOL bDraw, CSize& szIcon) const
{
if (!pItem)
return GetPaintManager()->m_bShowIcons;
if (pItem->GetImageIndex() == -1 || GetPaintManager()->m_bShowIcons == FALSE)
return FALSE;
CXTPImageManagerIcon* pImage = GetImageManager()->GetImage(pItem->GetImageIndex(), szIcon.cx);
if (!pImage)
return FALSE;
if (!bDraw)
{
return TRUE;
}
pItem->DrawImage(pDC, CRect(pt, szIcon), pImage);
return TRUE;
}
void CXTPRibbonControlTab::RedrawControl(LPCRECT lpRect, BOOL bAnimate)
{
m_pParent->Redraw(lpRect, bAnimate);
}
void CXTPRibbonControlTab::OnUnderlineActivate()
{
SetFocused(TRUE);
}
BOOL CXTPRibbonControlTab::HeaderHasFocus() const
{
return IsFocused() && m_pParent->IsTrackingMode();
}
BOOL CXTPRibbonControlTab::OnSetSelected(int bSelected)
{
if (bSelected == m_bSelected)
return FALSE;
if (IsKeyboardSelected(bSelected) && !GetRibbonBar()->IsRibbonMinimized())
m_pParent->SetPopuped(-1);
m_bSelected = bSelected;
m_pParent->OnControlSelected(bSelected, this);
if (IsKeyboardSelected(bSelected))
{
SetFocused(TRUE);
}
if (!bSelected)
{
SetFocused(FALSE);
PerformMouseMove(m_pParent->GetSafeHwnd(), CPoint(-1, -1));
}
else
{
AccessibleNotifyWinEvent(EVENT_OBJECT_FOCUS , GetParent()->GetSafeHwnd(), GetID(), GetCurSel() + 1);
}
return TRUE;
}
BOOL CXTPRibbonControlTab::IsFocusable() const
{
return TRUE;
}
BOOL CXTPRibbonControlTab::IsFocused() const
{
return m_bFocused;
}
void CXTPRibbonControlTab::Draw(CDC* /*pDC*/)
{
}
BOOL CXTPRibbonControlTab::IsPopupBarTracking() const
{
return m_pCommandBar && m_pCommandBar->IsTrackingMode();
}
void CXTPRibbonControlTab::SetFocused(BOOL bFocused)
{
if (m_bFocused == bFocused)
return;
m_bFocused = bFocused;
if (m_bFocused && GetSelectedItem() == NULL)
{
SetSelectedItem(FindNextFocusable(-1, +1));
}
RedrawParent();
}
BOOL CXTPRibbonControlTab::OnHookKeyDown(UINT nChar, LPARAM /*lParam*/)
{
if (!IsFocused())
return FALSE;
UINT nCharLayout(nChar);
CXTPDrawHelpers::KeyToLayout(m_pParent, nCharLayout);
if (nCharLayout == VK_UP || nCharLayout == VK_DOWN || nCharLayout == VK_LEFT || nCharLayout == VK_RIGHT)
{
m_pParent->HideKeyboardTips();
}
if (nCharLayout == VK_LEFT && FindNextFocusable(GetCurSel(), -1))
{
if (PerformKeyDown(m_pParent->GetSafeHwnd(), nChar))
return TRUE;
}
if (nCharLayout == VK_RIGHT && FindNextFocusable(GetCurSel(), +1))
{
if (PerformKeyDown(m_pParent->GetSafeHwnd(), nChar))
return TRUE;
}
if (nCharLayout == VK_DOWN)
{
m_pParent->SetSelected(m_pControls->GetNext(CXTPControl::GetIndex(), +1), TRUE_KEYBOARD_NEXT);
return TRUE;
}
if (nCharLayout == VK_RETURN || nCharLayout == VK_SPACE && GetRibbonBar()->IsRibbonMinimized())
{
ShowPopupBar(TRUE);
return TRUE;
}
return FALSE;
}
void CXTPRibbonControlTab::OnClick(BOOL /*bKeyboard*/, CPoint /*pt*/)
{
// Do Nothing
}
BOOL CXTPRibbonControlTab::OnSetPopup(BOOL bPopup)
{
m_bPopup = bPopup;
if (bPopup)
{
ASSERT(GetSelectedItem());
CXTPRibbonTab* pSelectedTab = (CXTPRibbonTab*)GetSelectedItem();
if (!pSelectedTab || !GetRibbonBar()->IsRibbonMinimized())
{
m_bPopup = FALSE;
return FALSE;
}
if (m_pCommandBar)
m_pCommandBar->InternalRelease();
CXTPCommandBars* pCommandBars = GetRibbonBar()->GetCommandBars();
ASSERT(pCommandBars);
m_pCommandBar = GetRibbonBar()->CreateTabPopupToolBar(pSelectedTab);
m_pCommandBar->SetCommandBars(pCommandBars);
m_pCommandBar->EnableCustomization(FALSE);
m_pCommandBar->Popup(this, IsKeyboardSelected(GetSelected()));
}
else if (m_pCommandBar)
{
ASSERT(m_pCommandBar);
m_pCommandBar->SetTrackingMode(FALSE);
}
RedrawParent();
return TRUE;
}
void CXTPRibbonControlTab::Copy(CXTPControl* pControl, BOOL /*bRecursive = FALSE*/)
{
DeleteAllItems();
CXTPRibbonControlTab* pControlTab = (CXTPRibbonControlTab*)pControl;
for (int i = 0; i < pControlTab->GetItemCount(); i++)
{
CXTPRibbonTab* pTab = pControlTab->GetTab(i);
CXTPRibbonTab* pTabClone = (CXTPRibbonTab*)pTab->GetRuntimeClass()->CreateObject();
pTabClone->m_pRibbonBar = (CXTPRibbonBar*)GetParent();
pTabClone->m_pParent = (CXTPRibbonBar*)GetParent();
AddItem(i, pTabClone);
pTabClone->Copy(pTab);
}
}
void CXTPRibbonControlTab::DoPropExchange(CXTPPropExchange* pPX)
{
if (pPX->IsStoring())
{
long nCount = (long)m_arrItems.GetSize();
int i;
CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("Tab")));
POSITION posEnum = pEnumerator->GetPosition(nCount, FALSE);
for (i = 0; i < nCount; i++)
{
CXTPRibbonTab* pTab = (CXTPRibbonTab*)GetItem(i);
CXTPPropExchangeSection secItem(pEnumerator->GetNext(posEnum));
PX_Object(&secItem, pTab, RUNTIME_CLASS(CXTPRibbonTab));
}
}
else
{
CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("Tab")));
POSITION posEnum = pEnumerator->GetPosition(0, FALSE);
DeleteAllItems();
while (posEnum)
{
CXTPPropExchangeSection secItem(pEnumerator->GetNext(posEnum));
secItem->m_pOwner = this;
CXTPRibbonTab* pTab = NULL;
PX_Object(&secItem, pTab, RUNTIME_CLASS(CXTPRibbonTab));
if (!pTab)
AfxThrowArchiveException(CArchiveException::badClass);
AddItem(GetItemCount(), pTab);
}
}
}
//////////////////////////////////////////////////////////////////////////
// Accessible
HRESULT CXTPRibbonControlTab::GetAccessibleChildCount(long FAR* pChildCount)
{
if (pChildCount == 0)
return E_INVALIDARG;
*pChildCount = GetItemCount();
return S_OK;
}
HRESULT CXTPRibbonControlTab::GetAccessibleChild(VARIANT /*varChild*/, IDispatch* FAR* ppdispChild)
{
SAFE_MANAGE_STATE(m_pModuleState);
*ppdispChild = NULL;
return S_FALSE;
}
HRESULT CXTPRibbonControlTab::GetAccessibleName(VARIANT varChild, BSTR* pszName)
{
SAFE_MANAGE_STATE(m_pModuleState);
int nIndex = GetChildIndex(&varChild);
if (nIndex == CHILDID_SELF)
return CXTPControl::GetAccessibleName(varChild, pszName);
CXTPTabManagerItem* pItem = GetItem(nIndex - 1);
if (!pItem)
return E_INVALIDARG;
CString strCaption = pItem->GetCaption();
CXTPDrawHelpers::StripMnemonics(strCaption);
*pszName = strCaption.AllocSysString();
return S_OK;
}
HRESULT CXTPRibbonControlTab::GetAccessibleRole(VARIANT varChild, VARIANT* pvarRole)
{
pvarRole->vt = VT_I4;
pvarRole->lVal = GetChildIndex(&varChild) == CHILDID_SELF ? ROLE_SYSTEM_PAGETABLIST : ROLE_SYSTEM_PAGETAB;
return S_OK;
}
HRESULT CXTPRibbonControlTab::AccessibleSelect(long flagsSelect, VARIANT varChild)
{
SAFE_MANAGE_STATE(m_pModuleState);
int nIndex = GetChildIndex(&varChild);
if (nIndex == CHILDID_SELF)
return CXTPControl::AccessibleSelect(flagsSelect, varChild);
SetCurSel(nIndex - 1);
return S_OK;
}
HRESULT CXTPRibbonControlTab::GetAccessibleState(VARIANT varChild, VARIANT* pvarState)
{
int nIndex = GetChildIndex(&varChild);
if (nIndex == CHILDID_SELF)
{
pvarState->vt = VT_I4;
pvarState->lVal = STATE_SYSTEM_FOCUSABLE;
if (!m_pParent->IsVisible() || !IsVisible())
pvarState->lVal |= STATE_SYSTEM_INVISIBLE;
return S_OK;
}
CXTPTabManagerItem* pItem = GetItem(nIndex - 1);
if (!pItem)
return E_INVALIDARG;
pvarState->vt = VT_I4;
pvarState->lVal = STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_SELECTABLE;
if (pItem->IsSelected())
pvarState->lVal |= STATE_SYSTEM_SELECTED | STATE_SYSTEM_FOCUSED;
if (!pItem->IsVisible())
pvarState->lVal |= STATE_SYSTEM_INVISIBLE;
return S_OK;
}
HRESULT CXTPRibbonControlTab::GetAccessibleDefaultAction(VARIANT varChild, BSTR* pszDefaultAction)
{
if (GetChildIndex(&varChild) == CHILDID_SELF)
return CXTPControl::GetAccessibleDefaultAction(varChild, pszDefaultAction);
*pszDefaultAction = SysAllocString(L"Switch");
return S_OK;
}
HRESULT CXTPRibbonControlTab::AccessibleDoDefaultAction(VARIANT varChild)
{
SAFE_MANAGE_STATE(m_pModuleState);
int nIndex = GetChildIndex(&varChild);
if (nIndex == CHILDID_SELF)
return CXTPControl::AccessibleDoDefaultAction(varChild);
CXTPTabManagerItem* pItem = GetItem(nIndex - 1);
if (!pItem)
return E_INVALIDARG;
pItem->Select();
return S_OK;
}
HRESULT CXTPRibbonControlTab::AccessibleLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild)
{
*pxLeft = *pyTop = *pcxWidth = *pcyHeight = 0;
int nIndex = GetChildIndex(&varChild);
if (!m_pParent->GetSafeHwnd())
return S_OK;
if (!IsVisible())
return S_OK;
CRect rcControl = GetRect();
if (nIndex != CHILDID_SELF)
{
rcControl = GetItem(nIndex - 1)->GetRect();
}
m_pParent->ClientToScreen(&rcControl);
*pxLeft = rcControl.left;
*pyTop = rcControl.top;
*pcxWidth = rcControl.Width();
*pcyHeight = rcControl.Height();
return S_OK;
}
HRESULT CXTPRibbonControlTab::AccessibleHitTest(long xLeft, long yTop, VARIANT* pvarID)
{
if (pvarID == NULL)
return E_INVALIDARG;
pvarID->vt = VT_EMPTY;
if (!m_pParent->GetSafeHwnd())
return S_FALSE;
if (!CXTPWindowRect(m_pParent).PtInRect(CPoint(xLeft, yTop)))
return S_FALSE;
pvarID->vt = VT_I4;
pvarID->lVal = CHILDID_SELF;
CPoint pt(xLeft, yTop);
m_pParent->ScreenToClient(&pt);
if (!GetRect().PtInRect(pt))
return S_FALSE;
CXTPTabManagerItem* pItem = HitTest(pt);
if (pItem)
{
pvarID->lVal = pItem->GetIndex() + 1;
}
return S_OK;
}