29 #define YUILogComponent "ui-layout"
32 #include "YLayoutBox.h"
33 #include "YAlignment.h"
36 #include "YApplication.h"
46 , secondary( prim == YD_HORIZ ? YD_VERT : YD_HORIZ )
47 , debugLayout( false )
55 YUIDimension secondary;
66 YUI_CHECK_NEW( priv );
87 return priv->secondary;
94 return priv->debugLayout;
100 priv->debugLayout = deb;
102 yuiDebug() <<
"YLayoutBox: Layout debugging: " << std::boolalpha << deb << endl;
132 if ( dominatingChild )
184 double dominatingRatio = 0.0;
198 if ( ratio > dominatingRatio )
200 dominatingChild = child;
201 dominatingRatio = ratio;
209 if ( dominatingChild )
211 yuiDebug() <<
"Found dominating child: " << dominatingChild
218 yuiDebug() <<
"This layout doesn't have a dominating child." << endl;
222 return dominatingChild;
229 int maxPreferredSize = 0L;
235 maxPreferredSize = std::max( (*it)->preferredSize( dimension ), maxPreferredSize );
238 return maxPreferredSize;
245 int totalWeight = 0L;
251 totalWeight += (*it)->weight( dimension );
267 if ( ! (*it)->hasWeight( dimension ) )
268 size += (*it)->preferredSize( dimension );
284 if ( ! (*it)->hasWeight( dimension ) )
301 if ( ! (*it)->hasWeight( dimension ) &&
302 (*it)->stretchable( dimension ) )
319 if ( ! (*it)->hasWeight( dimension ) &&
336 if ( spacing && spacing->
stretchable( dimension ) )
351 if ( (*it)->stretchable( dimension ) ||
352 (*it)->hasWeight( dimension ) )
364 sizeVector widths ( count );
365 sizeVector heights ( count );
366 posVector x_pos ( count );
367 posVector y_pos ( count );
386 x_pos[i] = newWidth - x_pos[i] - widths[i];
389 doResize( widths, heights, x_pos, y_pos );
395 sizeVector & childSize,
396 posVector & childPos )
401 if ( distributableSize >= 0L )
408 int nonWeightedExtra = 0L;
411 int rubberBandExtra = 0L;
413 if ( totalWeight <= 0 )
421 if ( stretchableChildren > 0 )
422 nonWeightedExtra = distributableSize / stretchableChildren;
437 if ( surplusSize > 0L )
441 if ( rubberBands > 0 )
443 rubberBandExtra = surplusSize / rubberBands;
444 distributableSize -= rubberBandExtra * rubberBands;
451 yuiDebug() <<
"Distributing extra space" << endl;
452 yuiDebug() <<
"\tnew size: " << newSize << endl;
453 yuiDebug() <<
"\tdistributable size: " << distributableSize << endl;
454 yuiDebug() <<
"\trubber band extra: " << rubberBandExtra << endl;
455 yuiDebug() <<
"\trubber bands: " << rubberBands << endl;
456 yuiDebug() <<
"\ttotal weight: " << totalWeight << endl;
457 yuiDebug() <<
"\tnon weighted extra: " << nonWeightedExtra << endl;
471 childSize[i] = distributableSize * child->
weight(
primary() ) / totalWeight;
475 yuiDebug() <<
"Layout running out of space: "
476 <<
"Resizing child widget #" << i <<
" ("<< child
478 <<
" to " << childSize[i]
495 childSize[i] += nonWeightedExtra;
504 childSize[i] += rubberBandExtra;
523 int tooSmall = -distributableSize;
525 int totalMargins = 0L;
526 int remainingMargins = 0L;
527 double marginScale = 0.0;
529 yuiDebug() <<
"Not enough space: " << tooSmall <<
" too small - check the layout!" << endl;
538 if ( ! (*it)->hasWeight(
primary() ) )
545 yuiDebug() <<
"Found alignment with margins" << endl;
551 if ( totalMargins > tooSmall )
553 remainingMargins = totalMargins - tooSmall;
555 marginScale = ( (double) remainingMargins ) / totalMargins;
557 yuiDebug() <<
"Making up for insufficient space by reducing margins to "
558 << 100.0 * marginScale <<
"% - "
559 << remainingMargins <<
" left for margins"
564 tooSmall -= totalMargins;
566 yuiDebug() <<
"Reducing all margins to 0, but still " << tooSmall <<
" too small" << endl;
577 if ( ! (*it)->hasWeight(
primary() ) )
580 childSize[i] = (*it)->preferredSize(
primary() );
587 childSize[i] -= margins;
589 if ( remainingMargins > 0 )
591 margins = (int) marginScale * margins;
592 childSize[i] += margins;
593 remainingMargins -= margins;
609 int oldTooSmall = tooSmall;
610 int oldLoserCount = loserCount;
611 while ( tooSmall > 0 && loserCount > 0 )
615 yuiWarning() <<
"Distributing insufficient space of " << tooSmall
616 <<
" among " << loserCount <<
" losers"
620 int dividedLoss = std::max( tooSmall / loserCount, 1 );
627 if ( childSize[i] < dividedLoss )
633 if ( childSize[i] > 0L )
635 tooSmall -= childSize[i];
639 if ( loserCount > 0 )
640 dividedLoss = std::max( tooSmall / loserCount, 1 );
645 childSize[i] -= dividedLoss;
646 tooSmall -= dividedLoss;
653 yuiWarning() <<
"child #" << i <<
" ( " << child
654 <<
" ) will get " << childSize[i]
659 <<
"), pos: " << childPos[i]
664 if ( oldTooSmall == tooSmall &&
665 oldLoserCount == loserCount )
667 yuiWarning() <<
"Preventing endless loop while layout space distribution. Break." << endl;
671 oldTooSmall = tooSmall;
672 oldLoserCount = loserCount;
691 sizeVector & childSize,
692 posVector & childPos )
706 childSize[i] = newSize;
711 childSize[i] = preferred;
712 childPos [i] = ( newSize - preferred ) / 2;
715 if ( childSize[i] < preferred )
717 yuiDebug() <<
"Layout running out of space: "
718 <<
"Resizing child widget #" << i
720 <<
") below its preferred size of " << preferred
721 <<
" to " << childSize[i]
727 ( childSize[i] < preferred ? yuiWarning() : yuiDebug() )
730 <<
") will get " << childSize[i]
731 <<
" (preferred size: " << preferred
734 <<
"), pos: " << childPos[i]
754 child->
setSize( width[i], height[i] );
759 yuiMilestone() <<
" x: " << std::setw( 3 ) << x_pos[i]
760 <<
" y: " << std::setw( 3 ) << y_pos[i]
761 <<
" w: " << std::setw( 3 ) << width[i]
762 <<
" h: " << std::setw( 3 ) << height[i]
773 return primary() == YD_VERT ?
"YVBox" :
"YHBox";