39#define _Class _StackView
59 $(self, bind, inlets, (Dictionary *) style->
attributes);
75 if (subviews->count) {
81 int availableSize, requestedSize = 0;
91 availableSize -= this->spacing * (subviews->count - 1);
95 SDL_Size sizes[subviews->count];
97 for (
size_t i = 0; i < subviews->count; i++) {
99 View *subview = $(subviews, objectAtIndex, i);
103 switch (this->axis) {
105 requestedSize += sizes[i].h;
108 requestedSize += sizes[i].w;
114 for (
size_t i = 0; i < subviews->count; i++) {
115 const View *subview = $(subviews, objectAtIndex, i);
122 max(availableSize - requestedSize, 0) : 0;
126 const float scale = requestedSize ? availableSize / (float) requestedSize : 1.f;
128 for (
size_t j = 0; j < subviews->count; j++) {
130 const size_t i = this->reversed ? subviews->count - 1 - j : j;
132 View *subview = $(subviews, objectAtIndex, i);
134 switch (this->axis) {
136 subview->
frame.y = pos;
139 subview->
frame.x = pos;
143 SDL_Size subviewSize = sizes[i];
145 switch (this->axis) {
160 switch (this->distribution) {
165 switch (this->axis) {
167 subviewSize.h *= scale;
170 subviewSize.w *= scale;
176 switch (this->axis) {
178 subviewSize.h = max(availableSize / (
float) subviews->count, sizes[i].h);
181 subviewSize.w = max(availableSize / (
float) subviews->count, sizes[i].w);
187 const bool stretch = subview->
stretch && remaining;
189 const int share = --numStretch ? remaining / (numStretch + 1) : remaining;
190 switch (this->axis) {
192 subviewSize.h += share;
195 subviewSize.w += share;
203 switch (this->axis) {
205 remaining -= max(subview->
frame.h - sizes[i].h, 0);
206 subviewSize.h = subview->
frame.h;
209 remaining -= max(subview->
frame.w - sizes[i].w, 0);
210 subviewSize.w = subview->
frame.w;
217 switch (this->axis) {
221 subview->
frame.x = 0;
230 pos += subviewSize.h;
235 subview->
frame.y = 0;
244 pos += subviewSize.w;
248 pos += this->spacing;
262 SDL_Size
size = MakeSize(0, 0);
264 switch (this->axis) {
277 for (
size_t i = 0; i < subviews->count; i++) {
279 View *subview = $(subviews, objectAtIndex, i);
281 const SDL_Size subviewSize = $(subview,
sizeThatSatisfies, unspecified, unspecified);
283 switch (this->axis) {
285 size.w = max(
size.w, subviewSize.w);
286 size.h += subviewSize.h;
289 size.w += subviewSize.w;
290 size.h = max(
size.h, subviewSize.h);
295 switch (this->axis) {
304 if (subviews->count) {
305 switch (this->axis) {
307 size.h += this->spacing * (subviews->count - 1);
310 size.w += this->spacing * (subviews->count - 1);
323#pragma mark - StackView
338#pragma mark - Class lifecycle
346 ((ViewInterface *) clazz->interface)->init =
init;
349 ((ViewInterface *) clazz->interface)->sizeThatFits =
sizeThatFits;
351 ((StackViewInterface *) clazz->interface)->initWithFrame =
initWithFrame;
363 clazz = _initialize(&(
const ClassDef) {
365 .superclass =
_View(),
367 .interfaceSize =
sizeof(StackViewInterface),
static SDL_Size size(const Image *self)
static Array * visibleSubviews(const View *self)
const EnumName StackViewAxisNames[]
static View * init(View *self)
static void applyStyle(View *self, const Style *style)
static SDL_Size sizeThatFits(const View *self)
static StackView * initWithFrame(StackView *self, const SDL_Rect *frame)
const EnumName StackViewDistributionNames[]
static void initialize(Class *clazz)
static void layoutSubviews(View *self)
StackViews are containers that manage the arrangement of their subviews.
@ StackViewDistributionDefault
@ StackViewDistributionFillEqually
@ StackViewDistributionFill
@ StackViewAxisHorizontal
#define MakeInlets(...)
Creates a null-termianted array of Inlets.
#define MakeInlet(name, type, dest, data)
Creates an Inlet with the specified parameters.
static SDL_Size sizeThatSatisfies(View *self, ViewConstraint width, ViewConstraint height)
static void layoutWithSize(View *self, const SDL_Size *size)
static SDL_Rect bounds(const View *self)
#define ViewAlignmentMaskBottom
#define ViewAlignmentMaskTop
#define ViewAlignmentMaskMiddle
#define MakeConstraint(mode, value)
#define ViewAlignmentMaskHorizontal
#define ClampSize(size, min, max)
Clamps size to min and max, where a max of zero is unbounded.
#define ViewAlignmentMaskVertical
Inlets enable inbound data binding of View attributes through JSON.
StackViews are containers that manage the arrangement of their subviews.
A constraint offered by an ancestor View to a descendant during View::sizeThatSatisfies.
Views are the fundamental building blocks of ObjectivelyMVC user interfaces.
ViewAlignment alignment
The alignment.
void applyStyle(View *self, const Style *style)
Applies the given Style to this View.
int autoresizingMask
The ViewAutoresizing bitmask.
ViewPadding padding
The padding.
SDL_Size minSize
The minimum size this View may be resized to during layout.
layoutSubviews(View *self)
Arranges this View's immediate subviews within its (already final) frame.
SDL_Size maxSize
The maximum size this View may be resized to during layout.
bool stretch
Whether this View takes a share of the space its StackView leaves along its axis.
SDL_Rect frame
The frame, relative to the superview.