📄 bcgpdockbar.cpp
字号:
rectDockArea = &pControlBar->m_recentDockInfo.m_recentSliderInfo.m_rectDockedRect;
ClientToScreen (rectDockArea);
}
// if the bar is being placed on the exclusive row
// (with menu bar, for example) we should create a new row, put the
// bar on new row and put this row after/before the exclusive row
POSITION posSwapRow = NULL;
if (pRowToDock != NULL && pRowToDock->IsExclusiveRow () ||
pRowToDock != NULL && !pControlBar->DoesAllowSiblingBars () &&
!pRowToDock->IsEmpty ())
{
posSwapRow = m_lstDockBarRows.Find (pRowToDock);
ASSERT (posSwapRow != NULL);
pRowToDock = NULL;
}
if (pRowToDock == NULL)
{
POSITION posNewBar = NULL;
if (posSwapRow != NULL)
{
// the bar is inserted before the specified position in AddRow
posNewBar = posSwapRow;
if (!bOuterRow)
{
m_lstDockBarRows.GetNext (posNewBar);
}
}
else
{
posNewBar = bOuterRow ? m_lstDockBarRows.GetHeadPosition () : NULL;
}
pRowToDock = AddRow (posNewBar, bVertDock ? szBarSize.cx : szBarSize.cy);
}
ASSERT_VALID (pRowToDock);
// the bar should be placed on the existing row or new row
pRowToDock->AddControlBar (pControlBar, dockMethod, rectDockArea);
// if the bar suudently changed its size we need to resize the row again
CSize sizeBarNew = pControlBar->CalcFixedLayout (FALSE, !bVertDock);
if (sizeBarNew != szBarSize)
{
ResizeRow (pRowToDock, bVertDock ? sizeBarNew.cx : sizeBarNew.cy);
}
m_lstControlBars.AddTail (pControlBar);
AdjustDockingLayout ();
ShowWindow (SW_SHOW);
}
}
//----------------------------------------------------------------------------------//
CBCGPDockBarRow* CBCGPDockBar::FindRowByRect (CRect rectRow)
{
bool b;
CPoint pt = rectRow.TopLeft ();
ClientToScreen (&pt);
return RowFromPoint (pt, b);
}
//----------------------------------------------------------------------------------//
BOOL CBCGPDockBar::DockControlBarLeftOf (CBCGPControlBar* pBarToDock,
CBCGPControlBar* pTargetBar)
{
ASSERT_VALID (this);
ASSERT_VALID (pBarToDock);
ASSERT_VALID (pTargetBar);
CBCGPDockBarRow* pTargetRow = RowFromControlBar (pTargetBar);
if (pTargetRow == NULL)
{
return FALSE;
}
CRect rectTargetBar;
pTargetBar->GetWindowRect (rectTargetBar);
ScreenToClient (rectTargetBar);
BOOL bVertDock = !IsHorizontal ();
CSize szBarSize = pBarToDock->CalcFixedLayout (FALSE, !bVertDock);
CRect rectFinal;
if (IsHorizontal ())
{
rectFinal.SetRect (rectTargetBar.left - szBarSize.cx - 10,
rectTargetBar.top, rectTargetBar.left - 10, rectTargetBar.bottom);
}
else
{
rectFinal.SetRect (rectTargetBar.left,
rectTargetBar.top - szBarSize.cy - 10,
rectTargetBar.right, rectTargetBar.top - 10);
}
pBarToDock->PrepareToDock (this, DM_RECT);
ClientToScreen (rectFinal);
pTargetRow->m_bIgnoreBarVisibility = TRUE;
pTargetRow->AddControlBar (pBarToDock, DM_RECT, &rectFinal);
POSITION pos = m_lstControlBars.Find (pTargetBar);
ASSERT (pos != NULL);
m_lstControlBars.InsertBefore (pos, pBarToDock);
AdjustDockingLayout ();
FixupVirtualRects ();
pTargetRow->m_bIgnoreBarVisibility = FALSE;
return TRUE;
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::RemoveControlBar (CBCGPControlBar* pControlBar, BCGP_DOCK_METHOD /*dockMethod*/)
{
ASSERT_VALID (this);
ASSERT_VALID (pControlBar);
if (!m_lstControlBars.IsEmpty ())
{
POSITION pos = m_lstControlBars.Find (pControlBar);
if (pos != NULL)
{
m_lstControlBars.RemoveAt (pos);
// we need to reposition bars according to the new situation
// 1. expand bars that were stretched due to presence of this bar
// 2. remove empty rows
CBCGPDockBarRow* pRow = pControlBar->GetDockBarRow ();
if (pRow != NULL)
{
pRow->RemoveControlBar (pControlBar);
}
}
}
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::FixupVirtualRects ()
{
ASSERT_VALID (this);
for (POSITION pos = m_lstDockBarRows.GetHeadPosition (); pos != NULL;)
{
CBCGPDockBarRow* pNextRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pNextRow);
pNextRow->FixupVirtualRects (false);
}
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::RepositionBars (CRect& rectNewClientArea)
{
ASSERT_VALID (this);
CRect rectOldArea;
GetClientRect (rectOldArea);
CSize sizeNew = rectNewClientArea.Size ();
CSize sizeOld = rectOldArea.Size ();
if (sizeNew != sizeOld)
{
int nHorzOffset = sizeNew.cx - sizeOld.cx;
int nVertOffset = sizeNew.cy - sizeOld.cy;
for (POSITION pos = m_lstDockBarRows.GetHeadPosition (); pos != NULL;)
{
CBCGPDockBarRow* pNextRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pNextRow);
if (nHorzOffset != 0)
{
pNextRow->RepositionBars (rectNewClientArea, WMSZ_RIGHT, nHorzOffset > 0, abs (nHorzOffset));
}
if (nVertOffset != 0)
{
pNextRow->RepositionBars (rectNewClientArea, WMSZ_BOTTOM, nVertOffset > 0, abs (nVertOffset));
}
}
}
else
{
// sanity check
for (POSITION pos = m_lstDockBarRows.GetHeadPosition (); pos != NULL;)
{
CBCGPDockBarRow* pNextRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pNextRow);
pNextRow->ExpandStretchedBarsRect ();
}
}
}
//----------------------------------------------------------------------------------//
CBCGPDockBarRow* CBCGPDockBar::CreateRow (CBCGPDockBar* /*pParentDocBar*/, int nOffset, int nRowHeight)
{
ASSERT_VALID (this);
CBCGPDockBarRow* pRow = new CBCGPDockBarRow (this, nOffset, nRowHeight);
if (!pRow->Create ())
{
delete pRow;
return NULL;
}
return pRow;
}
//----------------------------------------------------------------------------------//
CBCGPDockBarRow* CBCGPDockBar::AddRow (POSITION posRowBefore, int nRowHeight)
{
ASSERT_VALID (this);
// claculate the row offset
int nOffset = 0;
for (POSITION pos = m_lstDockBarRows.GetHeadPosition (); pos != posRowBefore;)
{
CBCGPDockBarRow* pNextRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pNextRow);
if (pNextRow->IsVisible ())
{
nOffset += pNextRow->GetRowHeight ();
}
}
ResizeDockBarByOffset (nRowHeight);
CBCGPDockBarRow* pNewRow = CreateRow (this, nOffset, nRowHeight);
if (pNewRow == NULL)
{
ASSERT (FALSE);
return NULL;
}
if (posRowBefore != NULL)
{
POSITION pos = m_lstDockBarRows.InsertBefore (posRowBefore, pNewRow);
OnInsertRow (pos);
}
else
{
m_lstDockBarRows.AddTail (pNewRow);
}
return pNewRow;
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::RemoveRow (CBCGPDockBarRow* pRow)
{
ASSERT_VALID (this);
ASSERT_VALID (pRow);
ASSERT (!m_lstDockBarRows.IsEmpty ());
int nRowHeight = pRow->GetRowHeight ();
if (pRow->IsVisible ())
{
ResizeDockBarByOffset (-nRowHeight);
}
POSITION pos = m_lstDockBarRows.Find (pRow);
if (pos != NULL)
{
OnRemoveRow (pos);
m_lstDockBarRows.RemoveAt (pos);
delete pRow;
}
}
//----------------------------------------------------------------------------------//
int CBCGPDockBar::ResizeRow (CBCGPDockBarRow* pRow, int nNewSize, BOOL bAdjustLayout)
{
ASSERT_VALID (this);
ASSERT_VALID (pRow);
int nOffset = nNewSize - pRow->GetRowHeight ();
if (nOffset < 0 && !pRow->IsEmpty ())
{
CSize size = pRow->CalcFixedLayout (TRUE, IsHorizontal ());
if (IsHorizontal () && nNewSize - size.cy < 0 ||
!IsHorizontal () && nNewSize - size.cx < 0)
{
return 0;
}
}
int nActualOffset = OnResizeRow (pRow, nOffset);
ResizeDockBarByOffset (nActualOffset, bAdjustLayout);
return nActualOffset;
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::ShowRow (CBCGPDockBarRow* pRow, BOOL bShow, BOOL bAdjustLayout)
{
ASSERT_VALID (this);
ASSERT_VALID (pRow);
ASSERT (!m_lstDockBarRows.IsEmpty ());
POSITION pos = m_lstDockBarRows.Find (pRow);
OnShowRow (pos, bShow);
int nRowHeight = pRow->GetRowHeight ();
ResizeDockBarByOffset (bShow ? nRowHeight : -nRowHeight, bAdjustLayout);
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::OnInsertRow (POSITION pos)
{
ASSERT_VALID (this);
ASSERT (pos != NULL);
CBCGPDockBarRow* pNewRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pNewRow);
int nRowSize = pNewRow->GetRowHeight ();
// when the row is inserted, all control bars that belongs to the rows after new,
// should be moved down
while (pos != NULL)
{
CBCGPDockBarRow* pNextRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pNextRow);
pNextRow->Move (nRowSize);
}
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::OnRemoveRow (POSITION pos, BOOL bByShow)
{
ASSERT_VALID (this);
ASSERT (pos != NULL);
CBCGPDockBarRow* pRowToRemove = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pRowToRemove);
if (!pRowToRemove->IsVisible () && !bByShow)
{
return;
}
int nRowSize = pRowToRemove->GetRowHeight ();
while (pos != NULL)
{
CBCGPDockBarRow* pNextRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pNextRow);
pNextRow->Move (-nRowSize);
}
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::OnShowRow (POSITION pos, BOOL bShow)
{
ASSERT_VALID (this);
ASSERT (pos != NULL);
bShow ? OnInsertRow (pos) : OnRemoveRow (pos, TRUE);
}
//----------------------------------------------------------------------------------//
int CBCGPDockBar::OnResizeRow (CBCGPDockBarRow* pRowToResize, int nOffset)
{
ASSERT_VALID (this);
ASSERT_VALID (pRowToResize);
int nActualOffset = pRowToResize->Resize (nOffset);
POSITION pos = m_lstDockBarRows.Find (pRowToResize);
m_lstDockBarRows.GetNext (pos);
// skip to next row
while (pos != NULL)
{
CBCGPDockBarRow* pNextRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pNextRow);
pNextRow->Move (nActualOffset);
}
return nActualOffset;
}
//----------------------------------------------------------------------------------//
void CBCGPDockBar::SwapRows (CBCGPDockBarRow* pFirstRow, CBCGPDockBarRow* pSecondRow)
{
POSITION posFirstRow = m_lstDockBarRows.Find (pFirstRow);
POSITION posSecondRow = m_lstDockBarRows.Find (pSecondRow);
ASSERT (posFirstRow != NULL);
ASSERT (posSecondRow != NULL);
POSITION posTmp = posFirstRow;
FindNextVisibleRow (posTmp);
bool bSwapDown = (posTmp == posSecondRow);
if (!bSwapDown)
{
posTmp = posFirstRow;
FindNextVisibleRow (posTmp, FALSE);
if (posTmp != posSecondRow)
{
return;
}
}
m_lstDockBarRows.InsertAfter (posFirstRow, pSecondRow);
m_lstDockBarRows.InsertAfter (posSecondRow, pFirstRow);
m_lstDockBarRows.RemoveAt (posFirstRow);
m_lstDockBarRows.RemoveAt (posSecondRow);
int nRowHeight = pFirstRow->GetRowHeight ();
pSecondRow->Move (bSwapDown ? -nRowHeight : nRowHeight);
nRowHeight = pSecondRow->GetRowHeight ();
pFirstRow->Move (bSwapDown ? nRowHeight : -nRowHeight);
FixupVirtualRects ();
}
//----------------------------------------------------------------------------------//
CBCGPDockBarRow* CBCGPDockBar::RowFromPoint (CPoint pt, bool& bOuterRow) const
{
ASSERT_VALID (this);
bOuterRow = false;
CRect rectRow;
for (POSITION pos = m_lstDockBarRows.GetHeadPosition (); pos != NULL;)
{
CBCGPDockBarRow* pRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pRow);
if (!pRow->IsVisible ())
{
continue;
}
pRow->GetWindowRect (rectRow);
if (rectRow.PtInRect (pt))
{
return pRow;
}
}
CRect rectWnd;
GetWindowRect (&rectWnd);
if (IsHorizontal () && pt.y < rectWnd.top ||
!IsHorizontal () && pt.x < rectWnd.left)
{
bOuterRow = true;
}
return NULL;
}
//----------------------------------------------------------------------------------//
CBCGPDockBarRow* CBCGPDockBar::RowFromControlBar (CBCGPBaseControlBar* pBar) const
{
ASSERT_VALID (this);
ASSERT_VALID (pBar);
for (POSITION pos = m_lstDockBarRows.GetHeadPosition (); pos != NULL;)
{
CBCGPDockBarRow* pRow = (CBCGPDockBarRow*) m_lstDockBarRows.GetNext (pos);
ASSERT_VALID (pRow);
if (pRow->HasControlBar (pBar) != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -