@@ -90,68 +90,84 @@ namespace cycfi::elements
90
90
std::sort (elements.begin (), elements.end (),
91
91
[](layout_info lhs, layout_info rhs){ return lhs.index < rhs.index ; });
92
92
}
93
- }
94
93
95
- // //////////////////////////////////////////////////////////////////////////
96
- // Vertical Tiles
97
- // //////////////////////////////////////////////////////////////////////////
98
- view_limits vtile_element::limits (basic_context const & ctx) const
99
- {
100
- view_limits limits{{ 0.0 , 0.0 }, { full_extent, 0.0 }};
101
- for (std::size_t i = 0 ; i != size (); ++i)
94
+ template < bool IS_X_AXIS, class TILE_ELEMENT >
95
+ [[gnu::always_inline]] inline auto compute_limits (basic_context const & ctx, const TILE_ELEMENT &tile) -> view_limits
96
+ {
97
+ view_limits limits{{ 0.0 , 0.0 },
98
+ {IS_X_AXIS ? 0.0 : full_extent,
99
+ IS_X_AXIS ? full_extent : 0.0 }};
100
+ for (std::size_t i = 0 ; i != tile. size (); ++i)
102
101
{
103
- auto el = at (i).limits (ctx);
102
+ auto el = tile. at (i).limits (ctx);
104
103
105
- limits.min .y += el.min .y ;
106
- limits.max .y += el.max .y ;
107
- clamp_min (limits.min .x , el.min .x );
108
- clamp_max (limits.max .x , el.max .x );
104
+ limits.min .coord (IS_X_AXIS) += el.min .coord (IS_X_AXIS) ;
105
+ limits.max .coord (IS_X_AXIS) += el.max .coord (IS_X_AXIS) ;
106
+ clamp_min (limits.min .coord (! IS_X_AXIS) , el.min .coord (! IS_X_AXIS) );
107
+ clamp_max (limits.max .coord (! IS_X_AXIS) , el.max .coord (! IS_X_AXIS) );
109
108
}
110
109
111
- clamp_min (limits.max .x , limits.min .x );
112
- clamp_max (limits.max .y , full_extent);
110
+ clamp_min (limits.max .coord (! IS_X_AXIS) , limits.min .coord (! IS_X_AXIS) );
111
+ clamp_max (limits.max .coord (IS_X_AXIS) , full_extent);
113
112
return limits;
114
- }
115
-
116
- void vtile_element::layout (context const & ctx)
117
- {
118
- auto const sz = size ();
119
-
120
- // Collect min, max, and stretch information from each element.
121
- // Initially set the allocation sizes of each element to its minimum.
122
- std::vector<layout_info> info (sz);
123
- for (std::size_t i = 0 ; i != sz; ++i)
124
- {
125
- auto & elem = at (i);
113
+ }
114
+
115
+ template <bool IS_X_AXIS, class TILE_ELEMENT >
116
+ [[gnu::always_inline]] inline auto compute_layout (context const & ctx, TILE_ELEMENT &tile, std::vector<float > &tilePos) -> void
117
+ {
118
+ auto const sz = tile.size ();
119
+
120
+ // Collect min, max, and stretch information from each element.
121
+ // Initially set the allocation sizes of each element to its minimum.
122
+ std::vector<layout_info> info (sz);
123
+ for (std::size_t i = 0 ; i != sz; ++i)
124
+ {
125
+ auto & elem = tile.at (i);
126
126
auto limits = elem.limits (ctx);
127
- info[i].stretch = elem.stretch ().y ;
128
- info[i].min = limits.min .y ;
129
- info[i].max = limits.max .y ;
130
- info[i].alloc = limits.min .y ;
127
+ info[i].stretch = elem.stretch ().coord (IS_X_AXIS) ;
128
+ info[i].min = limits.min .coord (IS_X_AXIS) ;
129
+ info[i].max = limits.max .coord (IS_X_AXIS) ;
130
+ info[i].alloc = limits.min .coord (IS_X_AXIS) ;
131
131
info[i].index = i;
132
- }
133
-
134
- auto const left = ctx.bounds .left ;
135
- auto const right = ctx.bounds .right ;
136
- auto const top = ctx.bounds .top ;
137
- auto const height = ctx.bounds .height ( );
138
- // Compute the best fit for all elements
139
- allocate (height , info);
140
-
141
- // Now we have the final layout. We can now layout the individual
142
- // elements.
143
- _tiles .resize (sz);
144
- auto curr = 0 .0f ;
145
- for (std::size_t i = 0 ; i != sz; ++i)
146
- {
147
- _tiles [i] = curr + info[i].alloc ;
132
+ }
133
+
134
+ auto const otherMin = ctx.bounds .axisMin ( not IS_X_AXIS) ;
135
+ auto const otherMax = ctx.bounds .axisMax ( not IS_X_AXIS) ;
136
+ auto const myMin = ctx.bounds .axisMin (IS_X_AXIS) ;
137
+ auto const myDelta = ctx.bounds .axisDelta (IS_X_AXIS );
138
+ // Compute the best fit for all elements
139
+ allocate (myDelta , info);
140
+
141
+ // Now we have the final layout. We can now layout the individual
142
+ // elements.
143
+ tilePos .resize (sz);
144
+ auto curr = 0 .0f ;
145
+ for (std::size_t i = 0 ; i != sz; ++i)
146
+ {
147
+ tilePos [i] = curr + info[i].alloc ;
148
148
auto const prev = curr;
149
149
curr += info[i].alloc ;
150
150
151
- auto & elem = at (i);
152
- rect ebounds = {left, prev+top, right, curr+top};
151
+ auto & elem = tile.at (i);
152
+ auto ebounds = IS_X_AXIS
153
+ ? rect{prev+myMin, otherMin, curr+myMin, otherMax}
154
+ : rect{otherMin, prev+myMin, otherMax, curr+myMin};
153
155
elem.layout (context{ctx, &elem, ebounds});
154
- }
156
+ }
157
+ }
158
+ }
159
+
160
+ // //////////////////////////////////////////////////////////////////////////
161
+ // Vertical Tiles
162
+ // //////////////////////////////////////////////////////////////////////////
163
+ view_limits vtile_element::limits (basic_context const & ctx) const
164
+ {
165
+ return compute_limits<false >(ctx, *this );
166
+ }
167
+
168
+ void vtile_element::layout (context const & ctx)
169
+ {
170
+ compute_layout<false >(ctx, *this , _tiles);
155
171
}
156
172
157
173
void vtile_element::draw (context const & ctx)
@@ -176,61 +192,12 @@ namespace cycfi::elements
176
192
// //////////////////////////////////////////////////////////////////////////
177
193
view_limits htile_element::limits (basic_context const & ctx) const
178
194
{
179
- view_limits limits{{0.0 , 0.0 }, {0.0 , full_extent}};
180
- for (std::size_t i = 0 ; i != size (); ++i)
181
- {
182
- auto el = at (i).limits (ctx);
183
-
184
- limits.min .x += el.min .x ;
185
- limits.max .x += el.max .x ;
186
- clamp_min (limits.min .y , el.min .y );
187
- clamp_max (limits.max .y , el.max .y );
188
- }
189
-
190
- clamp_min (limits.max .y , limits.min .y );
191
- clamp_max (limits.max .x , full_extent);
192
- return limits;
195
+ return compute_limits<true >(ctx, *this );
193
196
}
194
197
195
198
void htile_element::layout (context const & ctx)
196
199
{
197
- auto const sz = size ();
198
-
199
- // Collect min, max, and stretch information from each element.
200
- // Initially set the allocation sizes of each element to its minimum.
201
- std::vector<layout_info> info (sz);
202
- for (std::size_t i = 0 ; i != sz; ++i)
203
- {
204
- auto & elem = at (i);
205
- auto limits = elem.limits (ctx);
206
- info[i].stretch = elem.stretch ().x ;
207
- info[i].min = limits.min .x ;
208
- info[i].max = limits.max .x ;
209
- info[i].alloc = limits.min .x ;
210
- info[i].index = i;
211
- }
212
-
213
- auto const top = ctx.bounds .top ;
214
- auto const bottom = ctx.bounds .bottom ;
215
- auto const left = ctx.bounds .left ;
216
- auto const width = ctx.bounds .width ();
217
- // Compute the best fit for all elements
218
- allocate (width, info);
219
-
220
- // Now we have the final layout. We can now layout the individual
221
- // elements.
222
- _tiles.resize (sz);
223
- auto curr = 0 .0f ;
224
- for (std::size_t i = 0 ; i != sz; ++i)
225
- {
226
- _tiles[i] = curr + info[i].alloc ;
227
- auto const prev = curr;
228
- curr += info[i].alloc ;
229
-
230
- auto & elem = at (i);
231
- rect ebounds = {prev+left, top, curr+left, bottom};
232
- elem.layout (context{ctx, &elem, ebounds});
233
- }
200
+ compute_layout<true >(ctx, *this , _tiles);
234
201
}
235
202
236
203
void htile_element::draw (context const & ctx)
0 commit comments