📄 rowlayoutpl.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: rowlayoutpl.cpp
// Purpose: cbRowLayoutPlugin implementation.
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 09/09/98
// RCS-ID: $Id: rowlayoutpl.cpp,v 1.11 2005/09/23 12:47:44 MR Exp $
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/fl/rowlayoutpl.h"
// exerimental "features" are still buggy
#undef __EXPERIMENTAL
/***** Implementation for class cbRowLayoutPlugin *****/
IMPLEMENT_DYNAMIC_CLASS( cbRowLayoutPlugin, cbPluginBase )
BEGIN_EVENT_TABLE( cbRowLayoutPlugin, cbPluginBase )
EVT_PL_LAYOUT_ROW ( cbRowLayoutPlugin::OnLayoutRow )
EVT_PL_LAYOUT_ROWS( cbRowLayoutPlugin::OnLayoutRows )
EVT_PL_RESIZE_ROW ( cbRowLayoutPlugin::OnResizeRow )
EVT_PL_INSERT_BAR ( cbRowLayoutPlugin::OnInsertBar )
EVT_PL_REMOVE_BAR ( cbRowLayoutPlugin::OnRemoveBar )
END_EVENT_TABLE()
cbRowLayoutPlugin::cbRowLayoutPlugin(void)
: mpPane( 0 )
{}
cbRowLayoutPlugin::cbRowLayoutPlugin( wxFrameLayout* pPanel, int paneMask )
: cbPluginBase( pPanel, paneMask ),
mpPane( 0 )
{}
void cbRowLayoutPlugin::CheckIfAtTheBoundary( cbBarInfo* pTheBar, cbRowInfo& rowInfo )
{
// this method handles situation, when fixed bar is inserted
// into the row, where among fixed bars not-fixed ones are present.
// In this case we need to check if the pBarNode appears to be inserted
// chain of fixed-bars on the very right or left side of the row,
// then all the white-space, such chain should be eliminated,
// and the resulting chain justified to the right or the left
// side of the row
if ( !pTheBar->IsFixed() || rowInfo.mHasOnlyFixedBars )
return;
cbBarInfo* pBar = rowInfo.mBars[ rowInfo.mBars.Count() - 1 ];
// slide fixed bars to the right on the right side relative to the pBarNode
int prevX = mpPane->mPaneWidth;
do
{
if ( !pBar->IsFixed() )
break;
wxRect& bounds = pBar->mBounds;
bounds.x = prevX - bounds.width;
prevX = bounds.x;
if ( pBar == pTheBar ) break;
pBar = pBar->mpPrev;
}
while( 1 );
// slide fixed bars to the left on the left side relative to the pBarNode
pBar = rowInfo.mBars[0];
prevX = 0;
do
{
if ( pBar->IsFixed() )
break;
wxRect& bounds = pBar->mBounds;
bounds.x = prevX;
prevX = bounds.x + bounds.width;
if ( pBar == pTheBar ) break;
pBar = pBar->mpNext;
}
while( 1 );
}
void cbRowLayoutPlugin::ExpandNotFixedBars( cbRowInfo* pRow )
{
ApplyLengthRatios( pRow );
#if 1
// FIXME:: something's wrong?
return;
#else
double freeSpc = (double)GetRowFreeSpace( pRow );
// calculate sum of precents
double pcntSum = 0.0;
size_t i;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
if ( !pRow->mBars[i]->IsFixed() )
pcntSum += pRow->mBars[i]->mLenRatio;
}
// setup bar lengths
int curX = 0;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
cbBarInfo& bar = *pRow->mBars[i];
if ( !bar.IsFixed() )
{
bar.mLenRatio = bar.mLenRatio/(pcntSum);
bar.mBounds.width =
wxMax( mpPane->mProps.mMinCBarDim.x, int( freeSpc*bar.mLenRatio ) );
}
bar.mBounds.x = curX;
curX = bar.mBounds.x + bar.mBounds.width;
}
#endif
}
void cbRowLayoutPlugin::AdjustLengthOfInserted( cbRowInfo* WXUNUSED(pRow), cbBarInfo* WXUNUSED(pTheBar) )
{
return;
#if 0
// TBD: Makes following code unreachable
// pTheBar is not-fixed
// FIXME:: what is this for??
#if 1
int totalLen = 0;
size_t i;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
if ( !pRow->mBars[i]->IsFixed() )
totalLen += pRow->mBars[i]->mBounds.width;
}
double curWidth = pTheBar->mBounds.width;
if ( pRow->mBars.Count() )
pTheBar->mBounds.width = int( mpPane->mPaneWidth * (curWidth / double(totalLen)) );
#else
double freeSpc = (double)GetRowFreeSpace( pRow );
double pcntSum = 0.0;
size_t i;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
if ( !pRow->mBars[i]->IsFixed() )
pcntSum += pRow->mBars[i]->mLenRatio;
}
// if no longer "balanced", assume that `pTheBar' was previously
// removed from this row (kind of AI...)
if ( pcntSum < 0.98 )
pTheBar->mBounds.width = freeSpc * (1.0 - pcntSum);
#endif
#endif
}
void cbRowLayoutPlugin::FitBarsToRange( int from, int till,
cbBarInfo* pTheBar, cbRowInfo* pRow )
{
cbBarInfo* pFromBar;
cbBarInfo* pTillBar;
if ( pTheBar->mBounds.x > from )
{
// it's range from the left
pFromBar = pRow->mBars[0];
pTillBar = pTheBar;
}
else
{
pFromBar = pTheBar->mpNext;
pTillBar = NULL;
}
// calc free space in the range
cbBarInfo* pBar = pFromBar;
int freeSpc = till-from;
double pcntSum = 0;
while( pBar != pTillBar )
{
if ( pBar->IsFixed() )
freeSpc -= pBar->mBounds.width;
else
pcntSum += pBar->mLenRatio;
pBar = pBar->mpNext;
}
// adjust not-fixed bar sizes in the range
pBar = pFromBar;
while ( pBar != pTillBar )
{
if ( !pBar->IsFixed() )
{
pBar->mBounds.width =
wxMax( mpPane->mProps.mMinCBarDim.x,
(int)( ((double)freeSpc) * (pBar->mLenRatio/pcntSum) )
);
}
pBar = pBar->mpNext;
}
// layout range, starting from the left-most bar
pBar = pFromBar;
int prevX = from;
bool hasNotFixedBars = false;
while ( pBar != pTillBar )
{
wxRect& bounds = pBar->mBounds;
if ( !pBar->IsFixed() )
{
hasNotFixedBars = true;
freeSpc -= bounds.width;
}
bounds.x = prevX;
prevX = bounds.x + bounds.width;
pBar = pBar->mpNext;
}
// make width adjustment for the right-most bar in the range, due to
// lost precision when seting widths using f.p. length-ratios
if ( hasNotFixedBars )
{
if ( pTheBar->mBounds.x > from )
{
if ( pTillBar->mpPrev )
{
wxRect& tillBar = pTillBar->mpPrev->mBounds;
//tillBar.width = bar.mBounds.x - tillBar.x;
tillBar.width += freeSpc;
}
}
else
{
cbBarInfo* pLast = pRow->mBars[ pRow->mBars.Count() - 1 ];
if ( pLast != pTheBar )
{
pTheBar->mBounds.width += freeSpc;
SlideRightSideBars( pTheBar );
}
}
}
}
void cbRowLayoutPlugin::MinimzeNotFixedBars( cbRowInfo* pRow, cbBarInfo* pBarToPreserve )
{
size_t i;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
if ( !pRow->mBars[i]->IsFixed() && pRow->mBars[i] != pBarToPreserve )
pRow->mBars[i]->mBounds.width = mpPane->mProps.mMinCBarDim.x;
}
}
int cbRowLayoutPlugin::GetRowFreeSpace( cbRowInfo* pRow )
{
int freeSpc = mpPane->mPaneWidth;
size_t i;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
// not-fixed bars variable length, thus their
// dimensions are ignored
if ( pRow->mBars[i]->IsFixed() )
freeSpc -= pRow->mBars[i]->mBounds.width;
}
return freeSpc;
}
void cbRowLayoutPlugin::RecalcLengthRatios( cbRowInfo* pRow )
{
double freeSpc = double( GetRowFreeSpace( pRow ) );
cbBarInfo* pBar = pRow->mBars[0];
cbBarInfo* pLastNotFixed = NULL;
double pcntLeft = 1.0; // (100%)
#ifdef __EXPERIMENTAL
int totalLen = 0;
size_t i;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
if ( !pRow->mBars[i]->IsFixed() )
totalLen += pRow->mBars[i]->mBounds.width;
}
#endif
size_t i;
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
cbBarInfo& bar = *pRow->mBars[i];
if ( !bar.IsFixed() )
{
#ifdef __EXPERIMENTAL
bar.mLenRatio = double(bar.mBounds.width)/double(totalLen);
#else
bar.mLenRatio = double(bar.mBounds.width)/freeSpc;
#endif
pcntLeft -= bar.mLenRatio;
pLastNotFixed = pBar;
}
}
// attach remainder (the result of lost precision) to the
// last not-fixed bar
#if !defined(__EXPERIMENTAL)
if ( pLastNotFixed )
pLastNotFixed->mLenRatio += pcntLeft;
#endif
}
void cbRowLayoutPlugin::ApplyLengthRatios( cbRowInfo* pRow )
{
size_t i;
double pcntSum = 0;
// FOR NOW:: all-in-one
for ( i = 0; i != pRow->mBars.Count(); ++i )
{
if ( !pRow->mBars[i]->IsFixed() )
pcntSum += pRow->mBars[i]->mLenRatio;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -