📄 bcgpdockbarrow.cpp
字号:
// BCGPDockBarRow.cpp: implementation of the CBCGPDockBarRow class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BCGPControlBar.h"
#include "BCGPDockBar.h"
#include "BCGPDockBarRow.h"
#include "BCGPAutoHideButton.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNAMIC(CBCGPDockBarRow, CObject)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBCGPDockBarRow::CBCGPDockBarRow (CBCGPDockBar* pParentDockBar, int nOffset, int nHeight) :
m_pParentDockBar (pParentDockBar), m_nRowOffset (nOffset),
m_nRowHeight (nHeight)
{
ASSERT_VALID (pParentDockBar);
m_dwRowAlignment = pParentDockBar->GetCurrentAlignment ();
m_nMinHeight = 0;
m_nExtraSpace = 0;
m_nExtraAlignment = BCGP_ROW_ALIGN_TOP;
m_bVisible = TRUE;
m_nRowSavedHeight = 0;
m_bIgnoreBarVisibility = FALSE;
}
//**********************************************************************************************
CBCGPDockBarRow::~CBCGPDockBarRow ()
{
}
//**********************************************************************************************
void CBCGPDockBarRow::AddControlBar (CBCGPControlBar* pControlBar, BCGP_DOCK_METHOD dockMethod,
LPCRECT lpRect, BOOL bAddLast)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
CRect rectRow;
CPoint ptOffset (0, 0);
if (lpRect != NULL && !IsRectEmpty (lpRect))
{
CRect rectDockBar;
m_pParentDockBar->GetClientRect (&rectDockBar);
GetWindowRect (rectRow);
if (IsHorizontal ())
{
ptOffset.x = lpRect->left - rectRow.left;
ptOffset.y = rectDockBar.top + m_nRowOffset;
}
else
{
ptOffset.x = rectDockBar.left + m_nRowOffset;
ptOffset.y = lpRect->top - rectRow.top;
}
}
else
{
int nAdditionalBarOffset = 0;
if (bAddLast)
{
nAdditionalBarOffset = CalcLastBarOffset ();
if (nAdditionalBarOffset > 0)
{
nAdditionalBarOffset += globalData.m_nAutoHideToolBarSpacing;
}
}
GetClientRect (rectRow);
if (IsHorizontal ())
{
ptOffset.x = rectRow.left + nAdditionalBarOffset;
ptOffset.y = m_nRowOffset;
// align the bar to the bottom of the row
if (m_nExtraAlignment == BCGP_ROW_ALIGN_BOTTOM)
{
ptOffset.y += m_nExtraSpace;
}
}
else
{
ptOffset.x = m_nRowOffset;
ptOffset.y = rectRow.top + nAdditionalBarOffset;
// align the bar to the right side of the row
if (m_nExtraAlignment == BCGP_ROW_ALIGN_BOTTOM)
{
ptOffset.x += m_nExtraSpace;
}
}
}
CSize szBarSize = pControlBar->CalcFixedLayout (FALSE, IsHorizontal ());
pControlBar->SetWindowPos (NULL, ptOffset.x, ptOffset.y, szBarSize.cx, szBarSize.cy,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
OnInsertControlBar (pControlBar);
pControlBar->UpdateVirtualRect ();
}
//**********************************************************************************************
void CBCGPDockBarRow::AddControlBarFromRow (CBCGPControlBar* pControlBar, BCGP_DOCK_METHOD dockMethod)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
CRect rectWnd;
pControlBar->GetWindowRect (&rectWnd);
int nOffsetOnRow = 0;
if (dockMethod == DM_MOUSE)
{
// position the bar at the mouse cursor
CPoint ptMouse;
GetCursorPos (&ptMouse);
m_pParentDockBar->ScreenToClient (&ptMouse);
CPoint ptHot = pControlBar->GetClientHotSpot ();
// take the grippers and borders int account
CRect rectClient;
pControlBar->GetClientRect (rectClient);
pControlBar->ClientToScreen (rectClient);
int nNCOffset = rectClient.left - rectWnd.left;
nOffsetOnRow = IsHorizontal () ? ptMouse.x - ptHot.x - nNCOffset:
ptMouse.y - ptHot.y - nNCOffset;
}
else
{
m_pParentDockBar->ScreenToClient (&rectWnd);
nOffsetOnRow = IsHorizontal () ? rectWnd.left : rectWnd.top;
}
CRect rectPos;
if (IsHorizontal ())
{
rectPos.SetRect (nOffsetOnRow, m_nRowOffset, nOffsetOnRow + rectWnd.Width (), m_nRowOffset + rectWnd.Height ());
}
else
{
rectPos.SetRect (m_nRowOffset, nOffsetOnRow, m_nRowOffset + rectWnd.Width (), nOffsetOnRow + rectWnd.Height ());
}
pControlBar->SetWindowPos (NULL, rectPos.left, rectPos.top, rectPos.right, rectPos.bottom,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
OnInsertControlBar (pControlBar);
pControlBar->UpdateVirtualRect ();
}
//**********************************************************************************************
void CBCGPDockBarRow::OnInsertControlBar (CBCGPControlBar* pControlBar)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
CRect rectBarWnd;
pControlBar->GetWindowRect (&rectBarWnd);
CBCGPControlBar* pPrevControlBar = NULL;
bool bWasInserted = false;
POSITION posSave = NULL;
// the existing bars are ordered from the left to right or from top to bottom
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
posSave = pos;
CBCGPControlBar* pBarWnd = DYNAMIC_DOWNCAST (CBCGPControlBar,
m_lstControlBars.GetNext (pos));
pPrevControlBar = pBarWnd;
ASSERT_VALID (pBarWnd);
// the new bar should be inserted before the next bar it is left of
bWasInserted = pBarWnd->IsLeftOf (rectBarWnd);
if (bWasInserted)
{
m_lstControlBars.InsertBefore (posSave, pControlBar);
break;
}
}
// if the bar wasn't inserted
if (!bWasInserted)
{
m_lstControlBars.AddTail (pControlBar);
}
UpdateVisibleState (TRUE);
int nNewRowHeight = IsHorizontal () ? rectBarWnd.Height () : rectBarWnd.Width ();
if (nNewRowHeight > GetRowHeight ())
{
m_pParentDockBar->ResizeRow (this, nNewRowHeight + m_nExtraSpace);
}
pControlBar->SetDockBarRow (this);
ArrangeBars (pControlBar);
}
//**********************************************************************************************
void CBCGPDockBarRow::RemoveControlBar (CBCGPControlBar* pControlBar)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
POSITION pos = m_lstControlBars.Find (pControlBar);
if (pos != NULL)
{
// expand the bar before it leaves the row
HDWP hdwp = NULL;
pControlBar->StretchBar (0xFFFF, hdwp);
m_lstControlBars.RemoveAt (pos);
pControlBar->SetDockBarRow (NULL);
if (!m_lstControlBars.IsEmpty ())
{
FixupVirtualRects (true, pControlBar);
// expand stretched bars (if any)
ExpandStretchedBars ();
//
UpdateVisibleState (FALSE);
// find the biggest control bar and resize the row according to its size
int nMaxBarSize = GetMaxBarSize (FALSE);
if (nMaxBarSize < GetRowHeight ())
{
m_pParentDockBar->ResizeRow (this, nMaxBarSize);
m_nRowHeight = nMaxBarSize;
}
}
else
{
m_pParentDockBar->RemoveRow (this);
}
}
}
//**********************************************************************************************
CSize CBCGPDockBarRow::CalcFixedLayout (BOOL bStretch, BOOL bHorz)
{
if (!m_bVisible)
{
if (IsHorizontal ())
{
return CSize (32767, 0);
}
return CSize (0, 32767);
}
BOOL bHorzBar = IsHorizontal ();
CSize sizeRequired (0, 0);
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pBar = DYNAMIC_DOWNCAST (CBCGPControlBar, m_lstControlBars.GetNext (pos));
ASSERT_VALID (pBar);
if (!pBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
CSize sizeBar = pBar->CalcFixedLayout (bStretch, bHorz);
if (bHorzBar)
{
sizeRequired.cx += sizeBar.cx;
sizeRequired.cy = max (sizeRequired.cy, sizeBar.cy);
}
else
{
sizeRequired.cx = max (sizeRequired.cx, sizeBar.cx);
sizeRequired.cy += sizeBar.cy;
}
}
if (bHorzBar && sizeRequired.cy > 0)
{
sizeRequired.cy += m_nExtraSpace;
}
if (!bHorzBar && sizeRequired.cx > 0)
{
sizeRequired.cx += m_nExtraSpace;
}
return sizeRequired;
}
//**********************************************************************************************
void CBCGPDockBarRow::OnResizeControlBar (CBCGPBaseControlBar* pControlBar)
{
}
//**********************************************************************************************
int CBCGPDockBarRow::Resize (int nOffset)
{
int nNewHeight = m_nRowHeight + nOffset;
int nActualOffset = nNewHeight - m_nRowHeight;
m_nRowHeight = nNewHeight;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pBar = DYNAMIC_DOWNCAST (CBCGPControlBar, m_lstControlBars.GetNext (pos));
if (pBar != NULL)
{
pBar->RecalcLayout ();
}
}
// return the actual resize offset
return nActualOffset;
}
//**********************************************************************************************
void CBCGPDockBarRow::Move (int nOffset)
{
ASSERT_VALID (this);
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pBar = DYNAMIC_DOWNCAST (CBCGPControlBar, m_lstControlBars.GetNext (pos));
if (pBar != NULL)
{
pBar->MoveByAlignment (m_dwRowAlignment, nOffset);
}
}
m_nRowOffset += nOffset;
}
//**********************************************************************************************
void CBCGPDockBarRow::GetWindowRect (CRect& rect) const
{
ASSERT_VALID (this);
rect.SetRectEmpty ();
if (m_pParentDockBar == NULL)
{
return;
}
m_pParentDockBar->GetWindowRect (&rect);
if (IsHorizontal ())
{
rect.top += m_nRowOffset;
rect.bottom = rect.top + GetRowHeight ();
}
else
{
rect.left += m_nRowOffset;
rect.right = rect.left + GetRowHeight ();
}
}
//**********************************************************************************************
void CBCGPDockBarRow::GetClientRect (CRect& rect) const
{
ASSERT_VALID (this);
GetWindowRect (rect);
m_pParentDockBar->ScreenToClient (&rect);
if (IsHorizontal ())
{
rect.top -= m_nRowOffset;
rect.bottom = rect.top + GetRowHeight ();
}
else
{
rect.left -= m_nRowOffset;
rect.right = rect.left + GetRowHeight ();
}
}
//**********************************************************************************************
void CBCGPDockBarRow::ScreenToClient (CRect& rect) const
{
ASSERT_VALID (this);
m_pParentDockBar->ScreenToClient (&rect);
}
//**********************************************************************************************
BOOL CBCGPDockBarRow::ShowControlBar (CBCGPControlBar* pControlBar, BOOL bShow,
BOOL bDelay)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
if (!HasControlBar (pControlBar))
{
return FALSE;
}
pControlBar->ShowWindow (bShow ? SW_SHOW : SW_HIDE);
UpdateVisibleState (bDelay);
if (!bShow)
{
ExpandStretchedBars ();
}
else
{
pControlBar->AdjustLayout ();
ArrangeBars (pControlBar);
}
if (!bDelay)
{
CRect rect;
GetClientRect (rect);
m_pParentDockBar->RepositionBars (rect);
RepositionBars (rect);
}
return TRUE;
}
//**********************************************************************************************
void CBCGPDockBarRow::UpdateVisibleState (BOOL bDelay)
{
BOOL bUseRecentVisibleState = !m_pParentDockBar->GetParent ()->IsWindowVisible ();
BOOL bOldVisibleState = m_bVisible;
BOOL bNewVisibleState = FALSE;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPBaseControlBar* pNextWnd = (CBCGPBaseControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextWnd);
if (bUseRecentVisibleState && pNextWnd->IsRestoredFromRegistry ())
{
bNewVisibleState = pNextWnd->GetRecentVisibleState ();
if (bNewVisibleState)
{
break;
}
}
else if (pNextWnd->GetStyle () & WS_VISIBLE)
{
bNewVisibleState = TRUE;
break;
}
}
if (bOldVisibleState != bNewVisibleState)
{
ShowDockBarRow (bNewVisibleState, bDelay);
}
m_bVisible = bNewVisibleState;
}
//**********************************************************************************************
void CBCGPDockBarRow::ShowDockBarRow (BOOL bShow, BOOL bDelay)
{
m_bVisible = bShow;
m_pParentDockBar->ShowRow (this, bShow, !bDelay);
}
//**********************************************************************************************
void CBCGPDockBarRow::ExpandStretchedBars ()
{
ASSERT_VALID (this);
if (m_lstControlBars.IsEmpty ())
{
return;
}
// do not use virt. rects - we need real row space
int nAvalableLen = GetAvailableLength (FALSE);
HDWP hdwp = NULL;
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
int nRetSize = pNextBar->StretchBar (nAvalableLen, hdwp);
nAvalableLen -= nRetSize;
if (nAvalableLen <= 0)
{
break;
}
}
ArrangeBars (NULL);
}
//**********************************************************************************************
void CBCGPDockBarRow::ExpandStretchedBarsRect ()
{
ASSERT_VALID (this);
if (m_lstControlBars.IsEmpty ())
{
return;
}
BeginTrans ();
// do not use virt. rects - we need real row space
int nAvalableLen = GetAvailableLengthRect ();
for (POSITION pos = m_lstControlBars.GetHeadPosition (); pos != NULL;)
{
CBCGPControlBar* pNextBar = (CBCGPControlBar*) m_lstControlBars.GetNext (pos);
ASSERT_VALID (pNextBar);
if (!pNextBar->IsVisible () && !m_bIgnoreBarVisibility)
{
continue;
}
int nRetSize = StretchBarRect (pNextBar, nAvalableLen);
nAvalableLen -= nRetSize;
if (nAvalableLen <= 0)
{
break;
}
}
ArrangeBarsRect (NULL);
CommitTrans ();
}
//**********************************************************************************************
void CBCGPDockBarRow::ShiftControlBars (CBCGPControlBar* pControlBar, int nOffset, BOOL bForward)
{
ASSERT_VALID (this);
ASSERT (!m_lstControlBars.IsEmpty ());
if (nOffset == 0)
{
return;
}
POSITION pos = NULL;
if (pControlBar != NULL)
{
pos = m_lstControlBars.Find (pControlBar);
}
else
{
pos = bForward ? m_lstControlBars.GetHeadPosition () : m_lstControlBars.GetTailPosition ();
pControlBar = (CBCGPControlBar*) m_lstControlBars.GetAt (pos);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -