Math: renamed Rect to Rectf, implemented Vector2u32 and Rectu32. Scenegraph: implemen...
[fail.git] / gui / HGroup.cpp
blob0ee4346c128a292470d60515a58df1763ac98e34
1 #include "HGroup.h"
2 #include "Theme.h"
3 #include <vector>
5 using namespace awful;
6 using namespace awful::gui;
8 HGroup::HGroup( ContainerWidget* pParent_ ) :
9 SimpleContainer( pParent_ ),
10 m_Spacing( 2.f )
14 void HGroup::calcMinMax()
16 SimpleContainer::calcMinMax();
18 bool bUnlimited = false;
19 math::Vector2f min, max;
20 float spacing = 0.f;
22 WidgetList::const_iterator it;
23 for( it = m_Children.begin(); it != m_Children.end(); ++it )
25 spacing += m_Spacing;
26 const math::Vector2f& cmin = ( *it )->getMinSize();
27 const math::Vector2f& cmax = ( *it )->getMaxSize();
29 min.x() += cmin.x();
30 max.x() += cmax.x();
31 if( !cmax.x() )
32 bUnlimited = true;
34 if( cmin.y() > min.y() )
35 min.y() = cmin.y();
37 if( cmax.y() > max.y() )
38 max.y() = cmax.y();
41 spacing -= m_Spacing;
42 min.x() += spacing;
43 max.x() += spacing;
45 if( max.y() && max.y() < min.y() )
46 max.y() = min.y();
48 if( bUnlimited )
49 max.x() = 0.f;
51 setMinSize( min );
52 setMaxSize( max );
55 enum WidgetLayoutState
57 s_Free,
58 s_Min,
59 s_Max
62 void HGroup::layout()
64 WidgetList::size_type numchildren = m_Children.size();
66 const math::Rectf& r( getRect() );
67 float FreeSpace = r.width() - m_Spacing * static_cast< float >( numchildren - 1 );
69 // Currently, all children have a weight of 1. I'll implement weighted layout
70 // if I need it (aka if I feel like it).
71 float TotalWeight = static_cast< float >( numchildren );
73 std::vector< WidgetLayoutState > states( numchildren );
74 bool bMoreSpace = true;
75 WidgetList::const_iterator it;
76 int i;
78 // Outer loop: loop until the inner loop manage to go through all the children
79 // without changing their layout state.
82 for( it = m_Children.begin(), i = 0; it != m_Children.end(); ++it, ++i )
84 const math::Vector2f& min = ( *it )->getMinSize();
85 const math::Vector2f& max = ( *it )->getMaxSize();
87 if( states[i] == s_Free )
89 float size = FreeSpace / TotalWeight;
90 if( size < min.x() )
92 states[i] = s_Min;
93 TotalWeight -= 1.f;
94 FreeSpace -= min.x();
95 bMoreSpace = false;
96 break;
99 if( max.x() && size > max.x() )
101 states[i] = s_Max;
102 TotalWeight -= 1.f;
103 FreeSpace -= max.x();
104 bMoreSpace = true;
105 break;
108 else
110 if( bMoreSpace && states[i] == s_Min )
112 TotalWeight += 1.f;
113 FreeSpace += min.x();
114 float size = FreeSpace / TotalWeight;
115 if( size > min.x() )
117 states[i] = s_Free;
118 break;
120 else
122 TotalWeight -= 1.f;
123 FreeSpace -= min.x();
127 if( !bMoreSpace && states[i] == s_Max )
129 TotalWeight += 1.f;
130 FreeSpace += max.x();
131 float size = FreeSpace / TotalWeight;
132 if( size < max.x() )
134 states[i] = s_Free;
135 break;
137 else
139 TotalWeight -= 1.f;
140 FreeSpace -= max.x();
145 } while( it != m_Children.end() );
147 math::Rectf crect;
149 for( it = m_Children.begin(), i = 0; it != m_Children.end(); ++it, ++i )
151 const math::Vector2f& min = ( *it )->getMinSize();
152 const math::Vector2f& max = ( *it )->getMaxSize();
154 crect.height() = r.height();
155 if( crect.height() < min.y() )
156 crect.height() = min.y();
157 if( max.y() && crect.height() > max.y() )
158 crect.height() = max.y();
160 switch( states[i] )
162 case s_Free:
163 crect.width() = FreeSpace / TotalWeight;
164 break;
166 case s_Min:
167 crect.width() = min.x();
168 break;
170 case s_Max:
171 crect.width() = max.x();
172 break;
175 ( *it )->setRect( crect );
176 crect.left() += crect.width() + m_Spacing;
179 SimpleContainer::layout();