1
/////////////////////////////////////////////////////////////////////////////
2
// Name: rowlayoutpl.cpp
3
// Purpose: cbRowLayoutPlugin implementation.
4
// Author: Aleksandras Gluchovas
7
// RCS-ID: $Id: rowlayoutpl.cpp,v 1.10 2005/02/25 20:38:16 ABX Exp $
8
// Copyright: (c) Aleksandras Gluchovas
9
// Licence: wxWindows licence
10
/////////////////////////////////////////////////////////////////////////////
13
#pragma implementation "rowlayoutpl.h"
16
// For compilers that support precompilation, includes "wx.h".
17
#include "wx/wxprec.h"
27
#include "wx/fl/rowlayoutpl.h"
29
// exerimental "features" are still buggy
32
/***** Implementation for class cbRowLayoutPlugin *****/
34
IMPLEMENT_DYNAMIC_CLASS( cbRowLayoutPlugin, cbPluginBase )
36
BEGIN_EVENT_TABLE( cbRowLayoutPlugin, cbPluginBase )
38
EVT_PL_LAYOUT_ROW ( cbRowLayoutPlugin::OnLayoutRow )
39
EVT_PL_LAYOUT_ROWS( cbRowLayoutPlugin::OnLayoutRows )
40
EVT_PL_RESIZE_ROW ( cbRowLayoutPlugin::OnResizeRow )
42
EVT_PL_INSERT_BAR ( cbRowLayoutPlugin::OnInsertBar )
43
EVT_PL_REMOVE_BAR ( cbRowLayoutPlugin::OnRemoveBar )
47
cbRowLayoutPlugin::cbRowLayoutPlugin(void)
51
cbRowLayoutPlugin::cbRowLayoutPlugin( wxFrameLayout* pPanel, int paneMask )
53
: cbPluginBase( pPanel, paneMask ),
57
void cbRowLayoutPlugin::CheckIfAtTheBoundary( cbBarInfo* pTheBar, cbRowInfo& rowInfo )
59
// this method handles situation, when fixed bar is inserted
60
// into the row, where among fixed bars not-fixed ones are present.
61
// In this case we need to check if the pBarNode appears to be inserted
62
// chain of fixed-bars on the very right or left side of the row,
63
// then all the white-space, such chain should be eliminated,
64
// and the resulting chain justified to the right or the left
67
if ( !pTheBar->IsFixed() || rowInfo.mHasOnlyFixedBars )
71
cbBarInfo* pBar = rowInfo.mBars[ rowInfo.mBars.Count() - 1 ];
73
// slide fixed bars to the right on the right side relative to the pBarNode
75
int prevX = mpPane->mPaneWidth;
79
if ( !pBar->IsFixed() )
82
wxRect& bounds = pBar->mBounds;
84
bounds.x = prevX - bounds.width;
88
if ( pBar == pTheBar ) break;
94
// slide fixed bars to the left on the left side relative to the pBarNode
96
pBar = rowInfo.mBars[0];
102
if ( pBar->IsFixed() )
106
wxRect& bounds = pBar->mBounds;
110
prevX = bounds.x + bounds.width;
112
if ( pBar == pTheBar ) break;
119
void cbRowLayoutPlugin::ExpandNotFixedBars( cbRowInfo* pRow )
121
ApplyLengthRatios( pRow );
125
// FIXME:: something's wrong?
130
double freeSpc = (double)GetRowFreeSpace( pRow );
132
// calculate sum of precents
134
double pcntSum = 0.0;
137
for ( i = 0; i != pRow->mBars.Count(); ++i )
139
if ( !pRow->mBars[i]->IsFixed() )
140
pcntSum += pRow->mBars[i]->mLenRatio;
147
for ( i = 0; i != pRow->mBars.Count(); ++i )
149
cbBarInfo& bar = *pRow->mBars[i];
151
if ( !bar.IsFixed() )
153
bar.mLenRatio = bar.mLenRatio/(pcntSum);
157
wxMax( mpPane->mProps.mMinCBarDim.x, int( freeSpc*bar.mLenRatio ) );
160
bar.mBounds.x = curX;
161
curX = bar.mBounds.x + bar.mBounds.width;
166
void cbRowLayoutPlugin::AdjustLengthOfInserted( cbRowInfo* WXUNUSED(pRow), cbBarInfo* WXUNUSED(pTheBar) )
172
// TBD: Makes following code unreachable
174
// pTheBar is not-fixed
176
// FIXME:: what is this for??
183
for ( i = 0; i != pRow->mBars.Count(); ++i )
185
if ( !pRow->mBars[i]->IsFixed() )
186
totalLen += pRow->mBars[i]->mBounds.width;
189
double curWidth = pTheBar->mBounds.width;
191
if ( pRow->mBars.Count() )
193
pTheBar->mBounds.width = int( mpPane->mPaneWidth * (curWidth / double(totalLen)) );
196
double freeSpc = (double)GetRowFreeSpace( pRow );
198
double pcntSum = 0.0;
201
for ( i = 0; i != pRow->mBars.Count(); ++i )
203
if ( !pRow->mBars[i]->IsFixed() )
204
pcntSum += pRow->mBars[i]->mLenRatio;
207
// if no longer "balanced", assume that `pTheBar' was previously
208
// removed from this row (kind of AI...)
210
if ( pcntSum < 0.98 )
212
pTheBar->mBounds.width = freeSpc * (1.0 - pcntSum);
219
void cbRowLayoutPlugin::FitBarsToRange( int from, int till,
220
cbBarInfo* pTheBar, cbRowInfo* pRow )
225
if ( pTheBar->mBounds.x > from )
227
// it's range from the left
228
pFromBar = pRow->mBars[0];
233
pFromBar = pTheBar->mpNext;
237
// calc free space in the range
239
cbBarInfo* pBar = pFromBar;
240
int freeSpc = till-from;
243
while( pBar != pTillBar )
245
if ( pBar->IsFixed() )
246
freeSpc -= pBar->mBounds.width;
248
pcntSum += pBar->mLenRatio;
253
// adjust not-fixed bar sizes in the range
257
while ( pBar != pTillBar )
259
if ( !pBar->IsFixed() )
261
pBar->mBounds.width =
262
wxMax( mpPane->mProps.mMinCBarDim.x,
263
(int)( ((double)freeSpc) * (pBar->mLenRatio/pcntSum) )
269
// layout range, starting from the left-most bar
273
bool hasNotFixedBars = false;
275
while ( pBar != pTillBar )
277
wxRect& bounds = pBar->mBounds;
279
if ( !pBar->IsFixed() )
281
hasNotFixedBars = true;
283
freeSpc -= bounds.width;
288
prevX = bounds.x + bounds.width;
293
// make width adjustment for the right-most bar in the range, due to
294
// lost precision when seting widths using f.p. length-ratios
296
if ( hasNotFixedBars )
298
if ( pTheBar->mBounds.x > from )
300
if ( pTillBar->mpPrev )
302
wxRect& tillBar = pTillBar->mpPrev->mBounds;
304
//tillBar.width = bar.mBounds.x - tillBar.x;
305
tillBar.width += freeSpc;
310
cbBarInfo* pLast = pRow->mBars[ pRow->mBars.Count() - 1 ];
312
if ( pLast != pTheBar )
314
pTheBar->mBounds.width += freeSpc;
316
SlideRightSideBars( pTheBar );
322
void cbRowLayoutPlugin::MinimzeNotFixedBars( cbRowInfo* pRow, cbBarInfo* pBarToPreserve )
325
for ( i = 0; i != pRow->mBars.Count(); ++i )
327
if ( !pRow->mBars[i]->IsFixed() && pRow->mBars[i] != pBarToPreserve )
328
pRow->mBars[i]->mBounds.width = mpPane->mProps.mMinCBarDim.x;
332
int cbRowLayoutPlugin::GetRowFreeSpace( cbRowInfo* pRow )
334
int freeSpc = mpPane->mPaneWidth;
337
for ( i = 0; i != pRow->mBars.Count(); ++i )
339
// not-fixed bars variable length, thus their
340
// dimensions are ignored
341
if ( pRow->mBars[i]->IsFixed() )
342
freeSpc -= pRow->mBars[i]->mBounds.width;
348
void cbRowLayoutPlugin::RecalcLengthRatios( cbRowInfo* pRow )
350
double freeSpc = double( GetRowFreeSpace( pRow ) );
352
cbBarInfo* pBar = pRow->mBars[0];
353
cbBarInfo* pLastNotFixed = NULL;
355
double pcntLeft = 1.0; // (100%)
357
#ifdef __EXPERIMENTAL
362
for ( i = 0; i != pRow->mBars.Count(); ++i )
364
if ( !pRow->mBars[i]->IsFixed() )
365
totalLen += pRow->mBars[i]->mBounds.width;
370
for ( i = 0; i != pRow->mBars.Count(); ++i )
372
cbBarInfo& bar = *pRow->mBars[i];
374
if ( !bar.IsFixed() )
377
#ifdef __EXPERIMENTAL
379
bar.mLenRatio = double(bar.mBounds.width)/double(totalLen);
381
bar.mLenRatio = double(bar.mBounds.width)/freeSpc;
384
pcntLeft -= bar.mLenRatio;
385
pLastNotFixed = pBar;
389
// attach remainder (the result of lost precision) to the
390
// last not-fixed bar
392
#if !defined(__EXPERIMENTAL)
396
pLastNotFixed->mLenRatio += pcntLeft;
401
void cbRowLayoutPlugin::ApplyLengthRatios( cbRowInfo* pRow )
406
// FOR NOW:: all-in-one
408
for ( i = 0; i != pRow->mBars.Count(); ++i )
410
if ( !pRow->mBars[i]->IsFixed() )
411
pcntSum += pRow->mBars[i]->mLenRatio;
415
pBar = node_to_first_bar_node( pRow );
419
cbBarInfo& bar = node_to_bar( pBar );
421
if ( !bar.IsFixed() )
423
bar.mLenRatio = pcntSum / bar.mLenRatio;
430
double freeSpc = GetRowFreeSpace( pRow );
432
// tricky stuff (improtant!):
433
// when not-fixed bar is removed from the row and there are
434
// still some other not-fixed ones left in that row, then
435
// the sum of mLenRatio's is no longer 1.0 - this is left
436
// intintionally to handle the case when the removed bar
437
// is returned right back to the row - so that it would retain
438
// it's original dimensions in this row (this is kind of AI...)
440
// The problem is - when it's remvoed, the sum of
441
// mLenRatio's is not in "balance", i.e. is < 1.0,
442
// it's possible to restore balance, but instead of that
443
// we artifically ajdust freeSpc value in a way that it would
444
// look like total of mLetRatio's is 1.0, thus original
445
// len. ratios are _preserved_:
450
double unit = freeSpc / pcntSum;
452
bool haveSquished = false;
454
for ( i = 0; i != pRow->mBars.Count(); ++i )
456
if ( !pRow->mBars[i]->IsFixed() )
458
cbBarInfo& bar = *pRow->mBars[i];
460
if ( int( unit * bar.mLenRatio ) < mpPane->mProps.mMinCBarDim.x )
464
bar.mBounds.width = -1; // mark as "squished"
466
pcntSum -= bar.mLenRatio;
468
freeSpc -= mpPane->mProps.mMinCBarDim.x;
474
unit = freeSpc / pcntSum;
476
for ( i = 0; i != pRow->mBars.Count(); ++i )
478
cbBarInfo& bar = *pRow->mBars[i];
480
bar.mBounds.x = prevX;
482
if ( !bar.IsFixed() )
484
if ( bar.mBounds.width == -1 )
486
bar.mBounds.width = mpPane->mProps.mMinCBarDim.x;
488
bar.mBounds.width = int( unit * bar.mLenRatio );
490
// a little bit of AI:
491
// memorize bar's height and width, when docked in
492
// the current orientation - by making the current
493
// dimensions to be "preffered" ones for this docking state
495
if ( !bar.IsFixed() )
497
bar.mDimInfo.mSizes[ bar.mState ].x = bar.mBounds.width;
498
bar.mDimInfo.mSizes[ bar.mState ].y = bar.mBounds.height;
502
prevX = bar.mBounds.x + bar.mBounds.width;
506
void cbRowLayoutPlugin::DetectBarHandles( cbRowInfo* pRow )
508
// first pass from left to right (detect left-side handles)
510
bool foundNotFixed = false;
513
for ( i = 0; i != pRow->mBars.Count(); ++i )
515
cbBarInfo& bar = *pRow->mBars[i];
517
bar.mHasLeftHandle = false;
519
if ( !bar.IsFixed() )
524
bar.mpPrev->IsFixed() )
526
bar.mHasLeftHandle = true;
528
foundNotFixed = true;
532
// pass from right to left (detect right-side handles)
534
foundNotFixed = false;
536
cbBarInfo* pBar = pRow->mBars[ pRow->mBars.Count() - 1 ];
540
pBar->mHasRightHandle = false;
542
if ( !pBar->IsFixed() )
548
pBar->mHasRightHandle = true;
550
foundNotFixed = true;
557
void cbRowLayoutPlugin::RelayoutNotFixedBarsAround( cbBarInfo* pTheBar, cbRowInfo* pRow )
559
if ( !pTheBar->mpPrev )
561
if ( !pTheBar->IsFixed() )
563
// this bar the first in the row, move it's
564
// left edge to the very left
565
pTheBar->mBounds.width += pTheBar->mBounds.x;
566
pTheBar->mBounds.x = 0;
570
FitBarsToRange( 0, pTheBar->mBounds.x, pTheBar, pRow );
572
if ( !pTheBar->mpNext )
574
if ( !pTheBar->IsFixed() )
576
// this bar is the last one, move it's
577
// right edge to the very right
579
pTheBar->mBounds.width = mpPane->mPaneWidth - pTheBar->mBounds.x;
583
FitBarsToRange( pTheBar->mBounds.x + pTheBar->mBounds.width, mpPane->mPaneWidth,
588
void cbRowLayoutPlugin::LayoutItemsVertically( cbRowInfo& row )
591
for ( i = 0; i != row.mBars.Count(); ++i )
593
cbBarInfo& bar = *row.mBars[i];
595
bar.mBounds.y = row.mRowY;
597
if ( !bar.IsFixed() )
599
// make all not-fixed bars of equal height
600
bar.mBounds.height = row.mRowHeight;
602
if ( row.mHasUpperHandle )
604
bar.mBounds.y += mpPane->mProps.mResizeHandleSize;
608
int cbRowLayoutPlugin::CalcRowHeight( cbRowInfo& row )
613
for ( i = 0; i != row.mBars.Count(); ++i )
615
maxHeight = wxMax( maxHeight, row.mBars[i]->mBounds.height );
620
void cbRowLayoutPlugin::StickRightSideBars( cbBarInfo* pToBar )
622
cbBarInfo* pBar = pToBar->mpNext;
623
cbBarInfo* pPrev = pToBar;
627
wxRect& cur = pBar->mBounds;
628
wxRect& prev = pPrev->mBounds;
630
cur.x = prev.x + prev.width;
637
void cbRowLayoutPlugin::SlideLeftSideBars( cbBarInfo* pTheBar )
639
// shift left-side-bars to the left (with respect to "theBar"),
640
// so that they would not obscured by each other
642
cbBarInfo* pBar = pTheBar->mpPrev;
643
cbBarInfo* pPrev = pTheBar;
647
wxRect& cur = pBar->mBounds;
648
wxRect& prev = pPrev->mBounds;
650
if ( cur.x + cur.width > prev.x )
652
cur.x = prev.x - cur.width;
659
void cbRowLayoutPlugin::SlideRightSideBars( cbBarInfo* pTheBar )
661
// shift right-side-bars to the right (with respect to "theBar"),
662
// so that they would not be obscured by each other
664
cbBarInfo* pBar = pTheBar->mpNext;
665
cbBarInfo* pPrev = pTheBar;
669
wxRect& cur = pBar->mBounds;
670
wxRect& prev = pPrev->mBounds;
672
if ( cur.x < prev.x + prev.width )
674
cur.x = prev.x + prev.width;
681
void cbRowLayoutPlugin::ShiftLeftTrashold( cbBarInfo* WXUNUSED(pTheBar), cbRowInfo& row )
683
wxRect& first = row.mBars[0]->mBounds;
687
row.mBars[0]->mBounds.x = 0;
689
SlideRightSideBars( row.mBars[0] );
693
void cbRowLayoutPlugin::ShiftRightTrashold( cbBarInfo* pTheBar, cbRowInfo& row )
695
wxRect& theBar = pTheBar->mBounds;
699
cbBarInfo* pBar = pTheBar;
701
// calculate free spece on the left side
707
wxRect& cur = pBar->mBounds;
711
wxRect& prev = pBar->mpPrev->mBounds;
713
leftFreeSpc += cur.x - prev.x - prev.width;
716
leftFreeSpc += cur.x;
729
int rightOverflow = 0;
731
if ( pTheBar->IsFixed() )
737
wxRect& cur = pBar->mBounds;
739
if ( cur.x + cur.width > mpPane->mPaneWidth )
741
rightOverflow = cur.x + cur.width - mpPane->mPaneWidth;
747
if ( rightOverflow > 0 )
749
if ( leftFreeSpc <= 0 ) return;
751
if ( pTheBar->mpNext )
753
wxRect& next = pTheBar->mpNext->mBounds;
755
// if there's enough space on the left, move over one half-obscured
756
// bar from the right to the left side with respect to "theBar"
758
if ( next.width < leftFreeSpc )
760
cbBarInfo* pNext = pTheBar->mpNext;
762
row.mBars.Remove( pNext );
764
row.mBars.Insert( pNext, row.mBars.Index( pTheBar ) );
766
next.x = theBar.x - next.width;
768
// re-setup mpPrev/mpNext references after insertion
770
mpPane->InitLinksForRow( &row );
774
StickRightSideBars( pTheBar );
775
SlideLeftSideBars ( pTheBar );
781
int leftShift = ( rightOverflow > leftFreeSpc )
785
theBar.x -= leftShift;
787
StickRightSideBars( pTheBar );
788
SlideLeftSideBars ( pTheBar );
792
} // end of if ( rightOverflow )
799
void cbRowLayoutPlugin::InsertBefore( cbBarInfo* pBeforeBar,
805
row.mBars.Insert( pTheBar, row.mBars.Index( pBeforeBar ) );
807
row.mBars.Add( pTheBar );
809
pTheBar->mpRow = &row;
812
void cbRowLayoutPlugin::DoInsertBar( cbBarInfo* pTheBar, cbRowInfo& row )
814
wxRect& theBar = pTheBar->mBounds;
817
if ( theBar.x < 0 && !node_to_bar( pTheBar ).IsFixed() )
820
theBar.width += theBar.x;
825
for ( i = 0; i != row.mBars.Count(); ++i )
827
cbBarInfo& bar = *row.mBars[i];
829
wxRect& cur = bar.mBounds;
831
// if bar hits the left edge
832
if ( theBar.x <= cur.x )
834
InsertBefore( &bar, pTheBar, row );
839
// if bar hits the right edge
840
if ( theBar.x <= cur.x + cur.width )
842
if ( theBar.x + theBar.width > cur.x + cur.width )
844
InsertBefore( bar.mpNext, pTheBar, row );
848
// otherwise the bar lies within the bounds of current bar
850
int leftDist = theBar.x - cur.x;
851
int rightDist = cur.x + cur.width - (theBar.x + theBar.width);
853
if ( leftDist < rightDist )
855
InsertBefore( &bar, pTheBar, row );
857
InsertBefore( bar.mpNext, pTheBar, row );
863
InsertBefore( NULL, pTheBar, row ); // insert at the end
868
void cbRowLayoutPlugin::OnInsertBar( cbInsertBarEvent& event )
870
cbBarInfo* pBarToInsert = event.mpBar;
871
cbRowInfo* pIntoRow = event.mpRow;
872
mpPane = event.mpPane;
874
if ( !pBarToInsert->IsFixed() )
876
AdjustLengthOfInserted( pIntoRow, pBarToInsert );
878
DoInsertBar( pBarToInsert, *pIntoRow );
880
mpPane->InitLinksForRow( pIntoRow ); // relink "mpNext/mpPrev"s
882
// perform relayouting of the bars after insertion
884
// init bar location info
885
pBarToInsert->mAlignment = event.mpPane->mAlignment;
886
pBarToInsert->mRowNo = event.mpPane->GetRowIndex( pIntoRow );
888
#ifdef __EXPERIMENTAL
890
if ( !pIntoRow->mHasOnlyFixedBars || !pBarToInsert->IsFixed() )
892
RecalcLengthRatios( pIntoRow );
896
MinimzeNotFixedBars( pIntoRow, pBarToInsert );
898
SlideLeftSideBars ( pBarToInsert );
899
SlideRightSideBars( pBarToInsert );
901
ShiftLeftTrashold ( pBarToInsert, *pIntoRow );
902
ShiftRightTrashold( pBarToInsert, *pIntoRow );
904
mpPane->SyncRowFlags( pIntoRow );
906
CheckIfAtTheBoundary( pBarToInsert, *pIntoRow );
908
if ( event.mpPane->IsHorizontal() )
910
pBarToInsert->mState = wxCBAR_DOCKED_HORIZONTALLY;
912
pBarToInsert->mState = wxCBAR_DOCKED_VERTICALLY;
914
if ( !pIntoRow->mHasOnlyFixedBars )
917
#ifdef __EXPERIMENTAL
919
ExpandNotFixedBars( pIntoRow );
922
RelayoutNotFixedBarsAround( pBarToInsert, pIntoRow );
923
RecalcLengthRatios( pIntoRow );
927
DetectBarHandles( pIntoRow );
929
// do proportional resizing of not-fixed bars
930
ApplyLengthRatios( pIntoRow );
933
// adjust the bar's docking state
935
// a little bit of AI:
936
// memorize bar's height and width, when docked in
937
// the current orientation - by making the current
938
// dimensions to be "preferred" ones for this docking state
940
if ( !pBarToInsert->IsFixed() )
942
cbBarInfo& bar = *pBarToInsert;
944
bar.mDimInfo.mSizes[ bar.mState ].x = bar.mBounds.width;
945
bar.mDimInfo.mSizes[ bar.mState ].y = bar.mBounds.height;
949
void cbRowLayoutPlugin::OnRemoveBar ( cbRemoveBarEvent& event )
951
cbBarInfo* pBar = event.mpBar;
952
mpPane = event.mpPane;
954
cbRowInfo* pRow = pBar->mpRow;
956
mpLayout->GetUpdatesManager().OnBarWillChange( pBar, pRow, event.mpPane );
958
// invalidate the whole row
959
//pFirst->mpRowInfo->mMgrData.mPrevBounds.x = -1;
961
pRow->mBars.Remove( pBar );
963
// rest bar information after removing it from the row
965
pBar->mHasLeftHandle = false;
966
pBar->mHasRightHandle = false;
968
mpPane->InitLinksForRow( pRow ); // relink "mpNext/mpPrev"s
970
if ( pRow->mBars.Count() == 0 )
972
// empty rows should not exist
974
event.mpPane->GetRowList().Remove( pRow );
978
mpPane->InitLinksForRows();
982
// force repainting of bars, in the row, from which the bar was removed
984
// FIXME:: really needed?
985
pRow->mBars[0]->mUMgrData.SetDirty(true);
987
// re-setup mHasOnlyFixedBars flag for the row information
988
event.mpPane->SyncRowFlags( pRow );
990
DetectBarHandles( pRow );
992
if ( !pRow->mHasOnlyFixedBars )
994
ExpandNotFixedBars( pRow );
998
void cbRowLayoutPlugin::OnLayoutRow( cbLayoutRowEvent& event )
1000
cbRowInfo* pRow = event.mpRow;
1001
mpPane = event.mpPane;
1003
MinimzeNotFixedBars( pRow, NULL );
1005
if ( !pRow->mHasOnlyFixedBars )
1007
// do proportional resizing of not-fixed bars
1008
ApplyLengthRatios( pRow );
1011
cbBarInfo& lastBar = *pRow->mBars[ pRow->mBars.Count() - 1 ];
1012
cbBarInfo& firstBar = *pRow->mBars[ 0 ];
1014
// FIXME:: Next line not used
1015
// wxRect& bounds = lastBar.mBounds;
1017
if ( lastBar.mBounds.x + lastBar.mBounds.width > mpPane->mPaneWidth )
1019
lastBar.mBounds.x = mpPane->mPaneWidth - lastBar.mBounds.width;
1021
// first simulate left-row-edge friction
1023
SlideLeftSideBars( &lastBar );
1025
if ( firstBar.mBounds.x < 0 )
1026
firstBar.mBounds.x = 0;
1028
// then left-row-edge function, though this
1029
// may cause some of the right-side bars going
1030
// out of row bounds, but left-side always
1031
// has the highest "priority"
1033
SlideRightSideBars( &firstBar );
1036
event.Skip(); // pass event to the next handler
1039
void cbRowLayoutPlugin::OnLayoutRows( cbLayoutRowsEvent& event )
1041
mpPane = event.mpPane;
1045
// FIXME:: Next line not used.
1046
// RowArrayT& arr = mpPane->GetRowList();
1049
for ( i = 0; i != mpPane->GetRowList().Count(); ++i )
1051
cbRowInfo& row = *mpPane->GetRowList()[ i ];
1052
//mpPane->CalcLengthRatios(& row);
1054
// setup "has-handle" flags for rows, which depend on the existence
1055
// of not-fixed bars in the row
1057
if ( !row.mHasOnlyFixedBars )
1059
if ( mpPane->mAlignment == FL_ALIGN_TOP ||
1060
mpPane->mAlignment == FL_ALIGN_LEFT )
1062
row.mHasLowerHandle = true;
1064
row.mHasUpperHandle = false;
1068
row.mHasUpperHandle = true;
1070
row.mHasLowerHandle = false;
1075
// otherwise, rows with fixed-bars only, have no height-resizing handles
1076
row.mHasUpperHandle = false;
1077
row.mHasLowerHandle = false;
1080
// setup vertical positions for items in the row
1084
row.mRowWidth = mpPane->mPaneWidth;
1085
row.mRowHeight = CalcRowHeight( row );
1087
LayoutItemsVertically( row );
1089
if ( row.mHasUpperHandle )
1090
row.mRowHeight += mpPane->mProps.mResizeHandleSize;
1091
if ( row.mHasLowerHandle )
1092
row.mRowHeight += mpPane->mProps.mResizeHandleSize;
1094
curY += row.mRowHeight;
1097
event.Skip(); // pass event to the next handler - other hookeds plugin
1098
// may also add some "refinements" to the layout now
1101
void cbRowLayoutPlugin::OnResizeRow( cbResizeRowEvent& event )
1103
// extract resize-event info
1104
int ofs = event.mHandleOfs;
1105
bool forUpperHandle = event.mForUpperHandle;
1106
cbRowInfo* pTheRow = event.mpRow;
1107
mpPane = event.mpPane;
1109
// FIXME:: Next line not used.
1110
//int newHeight = pTheRow->mRowHeight;
1112
if ( forUpperHandle )
1114
// calculate available free space from above,
1115
// which can be obtained by squeezing not-fixed height rows
1117
cbRowInfo* pRow = pTheRow->mpPrev;
1121
pRow = pRow->mpPrev;
1126
// calculate available free space from below,
1127
// which can be obtained by squeezing not-fixed height rows
1129
cbRowInfo* pRow = pTheRow->mpNext;
1133
pRow = pRow->mpNext;
1137
mpLayout->GetUpdatesManager().OnStartChanges();
1141
// allow user adjusting pane vs. client-area space, for upper-handle
1143
if ( mpPane->IsHorizontal() )
1145
clientSize = mpLayout->GetClientHeight();
1147
clientSize = mpLayout->GetClientWidth();
1149
if ( forUpperHandle && ofs < -clientSize )
1151
int needed = -(ofs + clientSize);
1153
cbRowInfo* pRow = mpPane->GetRowList()[ 0 ];
1155
// start squeezing rows from the top row towards bottom
1157
while( pRow != pTheRow && needed )
1159
// only not-fixed rows can be squeezed
1161
if ( !pRow->mHasOnlyFixedBars )
1163
int prevHeight = pRow->mRowHeight;
1165
int newHeight = wxMax( event.mpPane->GetMinimalRowHeight( pRow ),
1166
prevHeight - needed );
1168
if ( newHeight != prevHeight )
1170
event.mpPane->SetRowHeight( pRow, newHeight );
1172
needed -= prevHeight - pRow->mRowHeight;
1176
pRow = pRow->mpNext;
1180
// allow user adjusting pane vs. client-area space, for lower-handle
1182
if ( !forUpperHandle && ofs > clientSize )
1184
int needed = ofs - clientSize;
1186
cbRowInfo* pRow = mpPane->GetRowList()[ mpPane->GetRowList().Count() - 1 ];
1188
// start squeezing rows from the bottom towards the top row
1190
while( pRow && needed )
1192
// only not-fixed rows can be squeezed
1194
if ( !pRow->mHasOnlyFixedBars )
1196
int prevHeight = pRow->mRowHeight;
1198
int newHeight = wxMax( event.mpPane->GetMinimalRowHeight( pRow ),
1199
prevHeight - needed );
1201
if ( newHeight != prevHeight )
1203
event.mpPane->SetRowHeight( pRow, newHeight );
1205
needed -= prevHeight - pRow->mRowHeight;
1209
pRow = pRow->mpPrev;
1213
if ( forUpperHandle )
1215
event.mpPane->SetRowHeight( pTheRow, pTheRow->mRowHeight + (-ofs) );
1217
event.mpPane->SetRowHeight( pTheRow, pTheRow->mRowHeight + ofs );
1219
mpLayout->RecalcLayout(false);
1221
mpLayout->GetUpdatesManager().OnFinishChanges();
1222
mpLayout->GetUpdatesManager().UpdateNow();