📄 rowlayoutpl.cpp
字号:
}
/*
pBar = node_to_first_bar_node( pRow );
while( pBar )
{
cbBarInfo& bar = node_to_bar( pBar );
if ( !bar.IsFixed() )
bar.mLenRatio = pcntSum / bar.mLenRatio;
pBar = pBar->Next();
}
*/
int prevX = 0;
double freeSpc = GetRowFreeSpace( pRow );
// tricky stuff (improtant!):
// when not-fixed bar is removed from the row and there are
// still some other not-fixed ones left in that row, then
// the sum of mLenRatio's is no longer 1.0 - this is left
// intintionally to handle the case when the removed bar
// is returned right back to the row - so that it would retain
// it's original dimensions in this row (this is kind of AI...)
//
// The problem is - when it's remvoed, the sum of
// mLenRatio's is not in "balance", i.e. is < 1.0,
// it's possible to restore balance, but instead of that
// we artifically ajdust freeSpc value in a way that it would
// look like total of mLetRatio's is 1.0, thus original
// len. ratios are _preserved_:
if (pcntSum == 0.0)
pcntSum = 1.0;
double unit = freeSpc / pcntSum;
bool haveSquished = false;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
if ( !pRow->mBars[i]->IsFixed() )
{
cbBarInfo& bar = *pRow->mBars[i];
if ( int( unit * bar.mLenRatio ) < mpPane->mProps.mMinCBarDim.x )
{
haveSquished = true;
bar.mBounds.width = -1; // mark as "squished"
pcntSum -= bar.mLenRatio;
freeSpc -= mpPane->mProps.mMinCBarDim.x;
}
}
} // for
if ( haveSquished )
unit = freeSpc / pcntSum;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
cbBarInfo& bar = *pRow->mBars[i];
bar.mBounds.x = prevX;
if ( !bar.IsFixed() )
{
if ( bar.mBounds.width == -1 )
bar.mBounds.width = mpPane->mProps.mMinCBarDim.x;
else
bar.mBounds.width = int( unit * bar.mLenRatio );
// a little bit of AI:
// memorize bar's height and width, when docked in
// the current orientation - by making the current
// dimensions to be "preffered" ones for this docking state
if ( !bar.IsFixed() )
{
bar.mDimInfo.mSizes[ bar.mState ].x = bar.mBounds.width;
bar.mDimInfo.mSizes[ bar.mState ].y = bar.mBounds.height;
}
}
prevX = bar.mBounds.x + bar.mBounds.width;
}
}
void cbRowLayoutPlugin::DetectBarHandles( cbRowInfo* pRow )
{
// first pass from left to right (detect left-side handles)
bool foundNotFixed = false;
size_t i;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
cbBarInfo& bar = *pRow->mBars[i];
bar.mHasLeftHandle = false;
if ( !bar.IsFixed() )
{
if ( foundNotFixed )
if ( bar.mpPrev &&
bar.mpPrev->IsFixed() )
bar.mHasLeftHandle = true;
foundNotFixed = true;
}
}
// pass from right to left (detect right-side handles)
foundNotFixed = false;
cbBarInfo* pBar = pRow->mBars[ pRow->mBars.Count() - 1 ];
while( pBar )
{
pBar->mHasRightHandle = false;
if ( !pBar->IsFixed() )
{
if ( foundNotFixed )
if ( pBar->mpNext )
pBar->mHasRightHandle = true;
foundNotFixed = true;
}
pBar = pBar->mpPrev;
}
}
void cbRowLayoutPlugin::RelayoutNotFixedBarsAround( cbBarInfo* pTheBar, cbRowInfo* pRow )
{
if ( !pTheBar->mpPrev )
{
if ( !pTheBar->IsFixed() )
{
// this bar the first in the row, move it's
// left edge to the very left
pTheBar->mBounds.width += pTheBar->mBounds.x;
pTheBar->mBounds.x = 0;
}
}
else
FitBarsToRange( 0, pTheBar->mBounds.x, pTheBar, pRow );
if ( !pTheBar->mpNext )
{
if ( !pTheBar->IsFixed() )
{
// this bar is the last one, move it's
// right edge to the very right
pTheBar->mBounds.width = mpPane->mPaneWidth - pTheBar->mBounds.x;
}
}
else
FitBarsToRange( pTheBar->mBounds.x + pTheBar->mBounds.width, mpPane->mPaneWidth,
pTheBar, pRow
);
}
void cbRowLayoutPlugin::LayoutItemsVertically( cbRowInfo& row )
{
size_t i;
for ( i = 0; i != row.mBars.Count(); ++i )
{
cbBarInfo& bar = *row.mBars[i];
bar.mBounds.y = row.mRowY;
if ( !bar.IsFixed() )
// make all not-fixed bars of equal height
bar.mBounds.height = row.mRowHeight;
if ( row.mHasUpperHandle )
bar.mBounds.y += mpPane->mProps.mResizeHandleSize;
}
}
int cbRowLayoutPlugin::CalcRowHeight( cbRowInfo& row )
{
int maxHeight = 0;
size_t i;
for ( i = 0; i != row.mBars.Count(); ++i )
maxHeight = wxMax( maxHeight, row.mBars[i]->mBounds.height );
return maxHeight;
}
void cbRowLayoutPlugin::StickRightSideBars( cbBarInfo* pToBar )
{
cbBarInfo* pBar = pToBar->mpNext;
cbBarInfo* pPrev = pToBar;
while( pBar )
{
wxRect& cur = pBar->mBounds;
wxRect& prev = pPrev->mBounds;
cur.x = prev.x + prev.width;
pPrev = pBar;
pBar = pBar->mpNext;
}
}
void cbRowLayoutPlugin::SlideLeftSideBars( cbBarInfo* pTheBar )
{
// shift left-side-bars to the left (with respect to "theBar"),
// so that they would not obscured by each other
cbBarInfo* pBar = pTheBar->mpPrev;
cbBarInfo* pPrev = pTheBar;
while( pBar )
{
wxRect& cur = pBar->mBounds;
wxRect& prev = pPrev->mBounds;
if ( cur.x + cur.width > prev.x )
cur.x = prev.x - cur.width;
pPrev = pBar;
pBar = pBar->mpPrev;
}
}
void cbRowLayoutPlugin::SlideRightSideBars( cbBarInfo* pTheBar )
{
// shift right-side-bars to the right (with respect to "theBar"),
// so that they would not be obscured by each other
cbBarInfo* pBar = pTheBar->mpNext;
cbBarInfo* pPrev = pTheBar;
while( pBar )
{
wxRect& cur = pBar->mBounds;
wxRect& prev = pPrev->mBounds;
if ( cur.x < prev.x + prev.width )
cur.x = prev.x + prev.width;
pPrev = pBar;
pBar = pBar->mpNext;
}
}
void cbRowLayoutPlugin::ShiftLeftTrashold( cbBarInfo* WXUNUSED(pTheBar), cbRowInfo& row )
{
wxRect& first = row.mBars[0]->mBounds;
if ( first.x < 0 )
{
row.mBars[0]->mBounds.x = 0;
SlideRightSideBars( row.mBars[0] );
}
}
void cbRowLayoutPlugin::ShiftRightTrashold( cbBarInfo* pTheBar, cbRowInfo& row )
{
wxRect& theBar = pTheBar->mBounds;
do
{
cbBarInfo* pBar = pTheBar;
// calculate free spece on the left side
int leftFreeSpc = 0;
while( pBar )
{
wxRect& cur = pBar->mBounds;
if ( pBar->mpPrev )
{
wxRect& prev = pBar->mpPrev->mBounds;
leftFreeSpc += cur.x - prev.x - prev.width;
}
else
leftFreeSpc += cur.x;
if ( cur.x < 0 )
{
leftFreeSpc = 0;
break;
}
pBar = pBar->mpPrev;
}
pBar = pTheBar;
int rightOverflow = 0;
if ( pTheBar->IsFixed() )
while( pBar )
{
if ( !pBar->mpNext )
{
wxRect& cur = pBar->mBounds;
if ( cur.x + cur.width > mpPane->mPaneWidth )
rightOverflow = cur.x + cur.width - mpPane->mPaneWidth;
}
pBar = pBar->mpNext;
}
if ( rightOverflow > 0 )
{
if ( leftFreeSpc <= 0 ) return;
if ( pTheBar->mpNext )
{
wxRect& next = pTheBar->mpNext->mBounds;
// if there's enough space on the left, move over one half-obscured
// bar from the right to the left side with respect to "theBar"
if ( next.width < leftFreeSpc )
{
cbBarInfo* pNext = pTheBar->mpNext;
row.mBars.Remove( pNext );
row.mBars.Insert( pNext, row.mBars.Index( pTheBar ) );
next.x = theBar.x - next.width;
// re-setup mpPrev/mpNext references after insertion
mpPane->InitLinksForRow( &row );
// tighten things
StickRightSideBars( pTheBar );
SlideLeftSideBars ( pTheBar );
continue;
}
}
int leftShift = ( rightOverflow > leftFreeSpc )
? leftFreeSpc
: rightOverflow;
theBar.x -= leftShift;
StickRightSideBars( pTheBar );
SlideLeftSideBars ( pTheBar );
break;
} // end of if ( rightOverflow )
else
break;
} while(1);
}
void cbRowLayoutPlugin::InsertBefore( cbBarInfo* pBeforeBar,
cbBarInfo* pTheBar,
cbRowInfo& row )
{
if ( pBeforeBar )
row.mBars.Insert( pTheBar, row.mBars.Index( pBeforeBar ) );
else
row.mBars.Add( pTheBar );
pTheBar->mpRow = &row;
}
void cbRowLayoutPlugin::DoInsertBar( cbBarInfo* pTheBar, cbRowInfo& row )
{
wxRect& theBar = pTheBar->mBounds;
/* OLD STUFF::
if ( theBar.x < 0 && !node_to_bar( pTheBar ).IsFixed() )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -