sproutcore 1.11.0.rc2 → 1.11.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG +10 -0
- data/VERSION.yml +1 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +114 -1
- data/lib/frameworks/sproutcore/apps/showcase/views/views_item_view.js +1 -7
- data/lib/frameworks/sproutcore/apps/showcase/views/views_list_view.js +9 -9
- data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +167 -5
- data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +24 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/stack_layout.js +737 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/layout.js +0 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +11 -7
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane_statechart.js +7 -11
- data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/child_view_layout_protocol.js +8 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/observable_protocol.js +9 -6
- data/lib/frameworks/sproutcore/frameworks/{desktop/protocols/responder.js → core_foundation/protocols/responder_protocol.js} +83 -17
- data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/{sparse_array_delegate.js → sparse_array_delegate_protocol.js} +11 -7
- data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/view_transition_protocol.js +11 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/color.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/page.js +0 -22
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +61 -56
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/main_pane.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/append_remove.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/animation.js +63 -39
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/border_frame_test.js +28 -28
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/createLayer.js +10 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layout.js +102 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutDidChange.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +103 -103
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/replaceAllChildren_test.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/view.js +77 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/view_states_test.js +18 -17
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +42 -49
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +5 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +16 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +241 -102
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +1 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +0 -11
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/statechart.js +993 -610
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +6 -11
- data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +94 -27
- data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +133 -53
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +30 -35
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/writeDataHash.js +73 -29
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/conflictedStoreKeys_test.js +156 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/dataSourceCallbacks.js +61 -37
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/find.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +68 -39
- data/lib/frameworks/sproutcore/frameworks/designer/tests/coders/page.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +8 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +80 -14
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/{drag_data_source.js → drag_data_source_protocol.js} +16 -10
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/{drag_source.js → drag_source_protocol.js} +28 -26
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/{drop_target.js → drop_target_protocol.js} +73 -75
- data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/ui.js +39 -23
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +120 -97
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowSizeForContentIndex.js +26 -25
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/ui.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +5 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/{dividers.js → dividers_test.js} +38 -38
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +29 -14
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll_view.js +13 -18
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +41 -35
- data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +14 -14
- data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +41 -26
- data/lib/frameworks/sproutcore/frameworks/desktop/views/static_content.js +2 -12
- data/lib/frameworks/sproutcore/frameworks/foundation/gestures/tap.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +14 -10
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/gesturable.js +104 -63
- data/lib/frameworks/sproutcore/frameworks/foundation/protocols/swap_transition_protocol.js +9 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/auto_mixin_tests.js +1 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/auto_resize_test.js +33 -33
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/transitions/view_transitions_test.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/methods.js +0 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/transition_test.js +0 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +12 -8
- data/lib/frameworks/sproutcore/frameworks/media/resources/silence.mp3 +0 -0
- data/lib/frameworks/sproutcore/frameworks/media/tests/audio.js +69 -0
- data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +11 -4
- data/lib/frameworks/sproutcore/frameworks/runtime/protocols/mixin_protocol.js +150 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +447 -137
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +9 -15
- data/lib/frameworks/sproutcore/frameworks/runtime/system/set.js +19 -17
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +188 -16
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/template_view/panes/template.js +0 -3
- data/lib/frameworks/sproutcore/frameworks/template_view/tests/panes/template.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/template_view/tests/views/template/collection.js +43 -26
- data/lib/frameworks/sproutcore/frameworks/template_view/views/bindable_span.js +9 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list.css +0 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/scroll/scroll.css +3 -0
- data/sproutcore.gemspec +3 -3
- metadata +19 -17
- data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/horizontal_stack_layout.js +0 -465
- data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/vertical_stack_layout.js +0 -472
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/build.js +0 -87
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/build_children.js +0 -89
@@ -0,0 +1,737 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: SproutCore
|
3
|
+
// Copyright: @2013 7x7 Software, Inc.
|
4
|
+
// License: Licensed under MIT license (see license.js)
|
5
|
+
// ==========================================================================
|
6
|
+
sc_require('views/view');
|
7
|
+
|
8
|
+
/** @private Shared stack plugin (may be horizontal or vertical). */
|
9
|
+
function _SC_VIEW_STACK_PLUGIN (direction) {
|
10
|
+
this.direction = direction;
|
11
|
+
}
|
12
|
+
|
13
|
+
/** @private Properties to observe on child views that affect the overall child view layout. */
|
14
|
+
_SC_VIEW_STACK_PLUGIN.prototype.childLayoutProperties = ['marginBefore', 'marginAfter', 'isVisible'];
|
15
|
+
|
16
|
+
/** @private When resizeToFit is false, then we need to know when the view's frame changes. */
|
17
|
+
_SC_VIEW_STACK_PLUGIN.prototype.layoutDependsOnSize = function (view) {
|
18
|
+
var options = view.get('childViewLayoutOptions');
|
19
|
+
|
20
|
+
if (options) {
|
21
|
+
return SC.none(options.resizeToFit) ? false : !options.resizeToFit;
|
22
|
+
} else {
|
23
|
+
return false;
|
24
|
+
}
|
25
|
+
};
|
26
|
+
|
27
|
+
/** @private */
|
28
|
+
_SC_VIEW_STACK_PLUGIN.prototype.layoutChildViews = function (view) {
|
29
|
+
var childViews = view.get('childViews'),
|
30
|
+
options = view.get('childViewLayoutOptions') || {},
|
31
|
+
resizeToFit = SC.none(options.resizeToFit) ? true : options.resizeToFit,
|
32
|
+
lastMargin = 0, // Used to avoid adding spacing to the final margin.
|
33
|
+
marginAfter = options.paddingBefore || 0,
|
34
|
+
paddingAfter = options.paddingAfter || 0,
|
35
|
+
firstPosition = 0,
|
36
|
+
provisionedSpace = 0,
|
37
|
+
autoFillAvailableSpace = 0,
|
38
|
+
totalAvailableSpace = 0,
|
39
|
+
totalFillAvailableSpaceRatio = 0,
|
40
|
+
spacing = options.spacing || 0,
|
41
|
+
sizeDimension = this.direction === 'vertical' ? 'height' : 'width',
|
42
|
+
minSizeDimension = this.direction === 'vertical' ? 'minHeight' : 'minWidth',
|
43
|
+
startDimension = this.direction === 'vertical' ? 'top' : 'left',
|
44
|
+
childView,
|
45
|
+
fillRatio,
|
46
|
+
layout,
|
47
|
+
marginBefore,
|
48
|
+
i, len;
|
49
|
+
|
50
|
+
// if the view is not configured to resize to fit content, then we give a chance to the children to fill the available space
|
51
|
+
// we make a 1st pass to check the conditions, to evaluate the available space and the proportions between children
|
52
|
+
if (!resizeToFit) {
|
53
|
+
|
54
|
+
totalAvailableSpace = view.get('frame')[sizeDimension];
|
55
|
+
|
56
|
+
// if the view is not configured to resize and it doesn't have yet a height/width, it doesn't make sense to layout children
|
57
|
+
if (!totalAvailableSpace) {
|
58
|
+
return;
|
59
|
+
}
|
60
|
+
|
61
|
+
for (i = 0, len = childViews.get('length'); i < len; i++) {
|
62
|
+
childView = childViews.objectAt(i);
|
63
|
+
|
64
|
+
// Ignore child views with useAbsoluteLayout true, useStaticLayout true or that are not visible.
|
65
|
+
if (!childView.get('isVisible') ||
|
66
|
+
childView.get('useAbsoluteLayout') ||
|
67
|
+
childView.get('useStaticLayout')) {
|
68
|
+
continue;
|
69
|
+
}
|
70
|
+
|
71
|
+
layout = childView.get('layout');
|
72
|
+
|
73
|
+
// Determine the top/left margin.
|
74
|
+
marginBefore = childView.get('marginBefore') || 0;
|
75
|
+
provisionedSpace += Math.max(marginAfter, marginBefore);
|
76
|
+
|
77
|
+
// if the height/width is not set, let's check if is possible to resize the view
|
78
|
+
if (SC.none(layout[sizeDimension])) {
|
79
|
+
fillRatio = childView.get('fillRatio');
|
80
|
+
|
81
|
+
if (!SC.none(fillRatio)) {
|
82
|
+
totalFillAvailableSpaceRatio += fillRatio;
|
83
|
+
} else {
|
84
|
+
// if none of the child views has fillRatio defined, allow the last one to stretch and fill the available space.
|
85
|
+
if (i === len - 1 && totalFillAvailableSpaceRatio === 0) {
|
86
|
+
totalFillAvailableSpaceRatio = 1;
|
87
|
+
}
|
88
|
+
//@if(debug)
|
89
|
+
// Add some developer support.
|
90
|
+
else {
|
91
|
+
// even if we don't have a height/width set, as last instance we accept the presence of minHeight/minWidth
|
92
|
+
if (SC.none(layout[minSizeDimension]))
|
93
|
+
{
|
94
|
+
if (this.direction === 'vertical') {
|
95
|
+
SC.warn('Developer Warning: The SC.View.VERTICAL_STACK plugin requires that each childView layout contains at least a height or has a configured fillRatio. The layout may also optionally contain left and right, left and width, right and width or centerX and width. The childView %@ has an invalid layout/fillRatio: %@'.fmt(childView, SC.stringFromLayout(layout)));
|
96
|
+
} else {
|
97
|
+
SC.warn('Developer Warning: The SC.View.HORIZONTAL_STACK plugin requires that each childView layout contains at least a width or has a configured fillRatio. The layout may also optionally contain top and bottom, top and height, bottom and height or centerY and height. The childView %@ has an invalid layout/fillRatio: %@'.fmt(childView, SC.stringFromLayout(layout)));
|
98
|
+
}
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
//@endif
|
103
|
+
}
|
104
|
+
} else {
|
105
|
+
provisionedSpace += childView.get('borderFrame')[sizeDimension];
|
106
|
+
}
|
107
|
+
|
108
|
+
// Determine the bottom/right margin.
|
109
|
+
lastMargin = childView.get('marginAfter') || 0;
|
110
|
+
marginAfter = lastMargin || spacing;
|
111
|
+
}
|
112
|
+
|
113
|
+
// consider the end padding when calculating the provisionedSpace
|
114
|
+
if (provisionedSpace !== 0 || totalFillAvailableSpaceRatio !== 0) {
|
115
|
+
provisionedSpace += Math.max(lastMargin, paddingAfter);
|
116
|
+
}
|
117
|
+
|
118
|
+
autoFillAvailableSpace = Math.max(0, totalAvailableSpace - provisionedSpace);
|
119
|
+
}
|
120
|
+
|
121
|
+
// reset the references for the effective layout
|
122
|
+
lastMargin = 0;
|
123
|
+
marginAfter = options.paddingBefore || 0;
|
124
|
+
paddingAfter = options.paddingAfter || 0;
|
125
|
+
|
126
|
+
for (i = 0, len = childViews.get('length'); i < len; i++) {
|
127
|
+
var size,
|
128
|
+
adjustStart,
|
129
|
+
adjustEnd;
|
130
|
+
|
131
|
+
childView = childViews.objectAt(i);
|
132
|
+
|
133
|
+
// Ignore child views with useAbsoluteLayout true, useStaticLayout true or that are not visible.
|
134
|
+
if (!childView.get('isVisible') ||
|
135
|
+
childView.get('useAbsoluteLayout') ||
|
136
|
+
childView.get('useStaticLayout')) {
|
137
|
+
continue;
|
138
|
+
}
|
139
|
+
|
140
|
+
layout = childView.get('layout');
|
141
|
+
|
142
|
+
//@if(debug)
|
143
|
+
// Add some developer support. The case of !resizeToFit was already checked above
|
144
|
+
if (resizeToFit && SC.none(layout[sizeDimension]) && SC.none(layout[minSizeDimension])) {
|
145
|
+
if (this.direction === 'vertical') {
|
146
|
+
SC.warn('Developer Warning: The SC.View.VERTICAL_STACK plugin, when configured with resizeToFit, requires that each childView layout contains at least a height/minHeight and optionally also left and right, left and width, right and width or centerX and width. The childView %@ has an invalid layout: %@'.fmt(childView, SC.stringFromLayout(layout)));
|
147
|
+
} else {
|
148
|
+
SC.warn('Developer Warning: The SC.View.HORIZONTAL_STACK plugin, when configured with resizeToFit, requires that each childView layout contains at least a width/minWidth and optionally also top and bottom, top and height, bottom and height or centerY and height. The childView %@ has an invalid layout: %@'.fmt(childView, SC.stringFromLayout(layout)));
|
149
|
+
}
|
150
|
+
return;
|
151
|
+
}
|
152
|
+
//@endif
|
153
|
+
|
154
|
+
// Determine the top/left margin.
|
155
|
+
marginBefore = childView.get('marginBefore') || 0;
|
156
|
+
firstPosition += Math.max(marginAfter, marginBefore);
|
157
|
+
|
158
|
+
// Try to avoid useless adjustments to top/left or bottom/right or top/left then bottom/right.
|
159
|
+
// The required adjustments will be merged into a single call
|
160
|
+
adjustStart = layout[startDimension] !== firstPosition;
|
161
|
+
|
162
|
+
childView.beginPropertyChanges();
|
163
|
+
if (!resizeToFit && !layout[sizeDimension]) {
|
164
|
+
var endDimension = this.direction === 'vertical' ? 'bottom' : 'right',
|
165
|
+
endPosition;
|
166
|
+
|
167
|
+
fillRatio = childView.get('fillRatio');
|
168
|
+
|
169
|
+
// if the last child doesn't define fillRatio, default it to 1 as above during the 1st pass
|
170
|
+
if (i === len - 1 && SC.none(fillRatio)) {
|
171
|
+
fillRatio = 1;
|
172
|
+
}
|
173
|
+
|
174
|
+
// we should get here only in two cases: 1. child defines fillRatio, 2. child defines a minHeight
|
175
|
+
// if both defined, we prefer to handle fillRatio, the other case being handled below by the normal adjustment to top/left
|
176
|
+
if (!SC.none(fillRatio)) {
|
177
|
+
var currentAvailableSpaceRatio = (fillRatio / totalFillAvailableSpaceRatio);
|
178
|
+
|
179
|
+
// calculate the height/width according to fillRatio and totalFillAvailableSpaceRatio
|
180
|
+
// but set the bottom/right position so any subsequent layout is not considering the height/width as fixed
|
181
|
+
size = Math.ceil(autoFillAvailableSpace * currentAvailableSpaceRatio);
|
182
|
+
|
183
|
+
// INCOMPLETE: We need to flag this view as constrained and re-compute all the auto-fill amounts
|
184
|
+
// Constrain the height/width to the maximum height/width allowed.
|
185
|
+
// var maxHeight = layout.maxHeight;
|
186
|
+
// if (!SC.none(maxHeight)) {
|
187
|
+
// // Constrain the height/width according to maxHeight/maxWidth. Which frees up additional available space for further child views.
|
188
|
+
// if (size > maxSize) {
|
189
|
+
// size = maxSize;
|
190
|
+
// }
|
191
|
+
// }
|
192
|
+
|
193
|
+
// Determine the bottom/right position. If the position overflows (i.e. goes negative) because of rounding up, stop at 0.
|
194
|
+
endPosition = Math.max(0, totalAvailableSpace - firstPosition - size);
|
195
|
+
adjustEnd = layout[endDimension] !== endPosition;
|
196
|
+
|
197
|
+
if (adjustEnd) {
|
198
|
+
childView.adjust(endDimension, endPosition);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
if (adjustStart) {
|
204
|
+
childView.adjust(startDimension, firstPosition);
|
205
|
+
}
|
206
|
+
childView.endPropertyChanges();
|
207
|
+
|
208
|
+
firstPosition += childView.get('borderFrame')[sizeDimension];
|
209
|
+
|
210
|
+
// Determine the bottom/right margin.
|
211
|
+
lastMargin = childView.get('marginAfter') || 0;
|
212
|
+
marginAfter = lastMargin || spacing;
|
213
|
+
}
|
214
|
+
|
215
|
+
// If the current size is 0 (all children are hidden), it doesn't make sense to add the padding
|
216
|
+
if (firstPosition !== 0) {
|
217
|
+
firstPosition += Math.max(lastMargin, paddingAfter);
|
218
|
+
}
|
219
|
+
|
220
|
+
// Adjust our frame to fit as well, this ensures that scrolling works.
|
221
|
+
if (resizeToFit && view.get('layout')[sizeDimension] !== firstPosition) {
|
222
|
+
view.adjust(sizeDimension, firstPosition);
|
223
|
+
}
|
224
|
+
};
|
225
|
+
|
226
|
+
|
227
|
+
SC.mixin(SC.View,
|
228
|
+
/** @scope SC.View */ {
|
229
|
+
|
230
|
+
/**
|
231
|
+
This child layout plugin automatically positions the view's child views in a
|
232
|
+
horizontal stack and optionally adjusts the view's width to fit. It does this
|
233
|
+
by checking the width of each child view and positioning the following child
|
234
|
+
views accordingly. Afterwards, by default, any time that a child view's
|
235
|
+
width or visibility changes, the view will use this plugin to re-adjust all
|
236
|
+
following child views' positions and potentially its own width appropriately.
|
237
|
+
|
238
|
+
This allows you to stack absolutely positioned views that dynamically change
|
239
|
+
their width and/or visibility without having to resort to using browser
|
240
|
+
flow layout.
|
241
|
+
|
242
|
+
For example,
|
243
|
+
|
244
|
+
MyApp.MyView = SC.View.extend({
|
245
|
+
|
246
|
+
// Child views will be stacked in order horizontally.
|
247
|
+
childViewLayout: SC.View.HORIZONTAL_STACK,
|
248
|
+
|
249
|
+
// The order of child views is important!
|
250
|
+
childViews: ['sectionA', 'sectionB', 'sectionC'],
|
251
|
+
|
252
|
+
// The view will resize itself to fit its children.
|
253
|
+
// i.e. We don't need to specify layout.width, this is automatic.
|
254
|
+
// The actual layout will become { left: 10, bottom: 20, top: 20, width: 270 } initially.
|
255
|
+
layout: { left: 10, bottom: 20, top: 20 },
|
256
|
+
|
257
|
+
sectionA: SC.View.design({
|
258
|
+
|
259
|
+
// We don't need to specify layout.left, this is automatic.
|
260
|
+
// The actual layout will become { left: 0, bottom: 0, top: 0, width: 100 } initially.
|
261
|
+
layout: { width: 100 }
|
262
|
+
|
263
|
+
}),
|
264
|
+
|
265
|
+
sectionB: SC.View.design({
|
266
|
+
|
267
|
+
// We don't need to specify layout.left, this is automatic.
|
268
|
+
// The actual layout will become { border: 1, left: 100, bottom: 0, top: 0, width: 50 } initially.
|
269
|
+
layout: { border: 1, width: 50 }
|
270
|
+
|
271
|
+
}),
|
272
|
+
|
273
|
+
sectionC: SC.View.design({
|
274
|
+
|
275
|
+
// We don't need to specify layout.left, this is automatic.
|
276
|
+
// The actual layout will become { left: 150, bottom: 10, top: 10, width: 120 } initially.
|
277
|
+
layout: { right: 10, top: 10, width: 120 }
|
278
|
+
|
279
|
+
})
|
280
|
+
|
281
|
+
});
|
282
|
+
|
283
|
+
## Modify the default behavior with `childViewLayoutOptions`
|
284
|
+
|
285
|
+
To modify the plugin behavior for all child view layouts, you can set the
|
286
|
+
following child view layout options in `childViewLayoutOptions` on the view:
|
287
|
+
|
288
|
+
- paddingBefore - Adds padding before the first child view. Default: 0
|
289
|
+
- paddingAfter - Adds padding after the last child view. Default: 0
|
290
|
+
- spacing - Adds spacing between each child view. Default: 0
|
291
|
+
- resizeToFit - Whether to resize the view to fit the child views (requires that each child view has a layout width). Default: true
|
292
|
+
|
293
|
+
For example,
|
294
|
+
|
295
|
+
MyApp.MyView = SC.View.extend({
|
296
|
+
|
297
|
+
// Child views will be stacked in order horizontally.
|
298
|
+
childViewLayout: SC.View.HORIZONTAL_STACK,
|
299
|
+
|
300
|
+
// Change the behavior of the HORIZONTAL_STACK plugin
|
301
|
+
childViewLayoutOptions: {
|
302
|
+
paddingBefore: 10,
|
303
|
+
paddingAfter: 20,
|
304
|
+
spacing: 5
|
305
|
+
},
|
306
|
+
|
307
|
+
// The order of child views is important!
|
308
|
+
childViews: ['sectionA', 'sectionB', 'sectionC'],
|
309
|
+
|
310
|
+
// The view will resize itself to fit its children. The actual layout will become { left: 10, bottom: 20, top: 20, width: 310 }
|
311
|
+
layout: { left: 10, bottom: 20, top: 20 }, // Don't need to specify layout.width, this is automatic.
|
312
|
+
|
313
|
+
sectionA: SC.View.design({
|
314
|
+
|
315
|
+
// Actual layout will become { left: 10, bottom: 0, top: 0, width: 100 }
|
316
|
+
layout: { width: 100 } // Don't need to specify layout.left, this is automatic.
|
317
|
+
|
318
|
+
}),
|
319
|
+
|
320
|
+
sectionB: SC.View.design({
|
321
|
+
|
322
|
+
// Actual layout will become { border: 1, left: 115, bottom: 0, top: 0, width: 50 }
|
323
|
+
layout: { border: 1, width: 50 } // Don't need to specify layout.left, this is automatic.
|
324
|
+
|
325
|
+
}),
|
326
|
+
|
327
|
+
sectionC: SC.View.design({
|
328
|
+
|
329
|
+
// Actual layout will become { left: 170, top: 10, bottom: 10, width: 120 }
|
330
|
+
layout: { top: 10, bottom: 10, width: 120 } // Don't need to specify layout.left, this is automatic.
|
331
|
+
|
332
|
+
})
|
333
|
+
|
334
|
+
});
|
335
|
+
|
336
|
+
If `resizeToFit` is set to `false`, the view will not adjust itself to fit
|
337
|
+
its child views. This means that when `resizeToFit` is false, the view should
|
338
|
+
specify its width component in its layout. A direct effect of this is the
|
339
|
+
possibility for the child views to automatically expand or shrink in order to
|
340
|
+
fill the empty, unclaimed space of the view.
|
341
|
+
|
342
|
+
This available space is shared between all children that don't specify a fixed width
|
343
|
+
such that their final width is calculated proportionally to the value of the
|
344
|
+
property `fillRatio`.
|
345
|
+
|
346
|
+
For simplicity, when none of the children specifies `fillRatio`,
|
347
|
+
you can ignore the last child view's layout width and the last child view
|
348
|
+
will stretch to fill the parent view.
|
349
|
+
|
350
|
+
For example,
|
351
|
+
|
352
|
+
MyApp.MyView = SC.View.extend({
|
353
|
+
|
354
|
+
// Child views will be stacked in order horizontally.
|
355
|
+
childViewLayout: SC.View.HORIZONTAL_STACK,
|
356
|
+
|
357
|
+
// Change the behavior of the HORIZONTAL_STACK plugin
|
358
|
+
childViewLayoutOptions: {
|
359
|
+
paddingBefore: 10,
|
360
|
+
paddingAfter: 20,
|
361
|
+
spacing: 5,
|
362
|
+
resizeToFit: false // Setting this to false, so that the child views stretch/contract to fit the parent's size.
|
363
|
+
},
|
364
|
+
|
365
|
+
// The order of child views is important!
|
366
|
+
childViews: ['sectionA', 'sectionB', 'sectionC'],
|
367
|
+
|
368
|
+
// The parent view will not resize itself to fit its contents, so we specify the width.
|
369
|
+
layout: { left: 10, bottom: 20, top: 20, width: 500 },
|
370
|
+
|
371
|
+
sectionA: SC.View.design({
|
372
|
+
|
373
|
+
// We don't need to specify layout.left, this is automatic. This child will not stretch, its width is set.
|
374
|
+
// Actual layout will become { left: 10, bottom: 0, top: 0, width: 100 }
|
375
|
+
layout: { width: 100 }
|
376
|
+
|
377
|
+
}),
|
378
|
+
|
379
|
+
sectionB: SC.View.design({
|
380
|
+
|
381
|
+
// The unclaimed space so far is 500 - 10 - 100 - 5 - 5 - 20, or 360px. This space will be shared between
|
382
|
+
// the two last sections, because we won't specity a width on them.
|
383
|
+
// This view will get 1/3 of the available space, because the other flexibile view has a ratio of 2.
|
384
|
+
fillRatio: 1,
|
385
|
+
|
386
|
+
// This section will take 1/3 * 360px = 120px.
|
387
|
+
// Actual layout will become { border: 1, left: 115, bottom: 0, top: 0, right: 265 }, in other words, width == 120
|
388
|
+
// We don't need to specify layout.left, layout.right or layout.width, this is automatic.
|
389
|
+
layout: { border: 1 }
|
390
|
+
|
391
|
+
}),
|
392
|
+
|
393
|
+
sectionC: SC.View.design({
|
394
|
+
|
395
|
+
// This view will get 2/3 of the available space, because the other flexibile view has a ratio of 1.
|
396
|
+
fillRatio: 2,
|
397
|
+
|
398
|
+
// This section will take 2/3 * 360px = 240px.
|
399
|
+
// Actual layout will become { left: 240, top: 10, bottom: 10, right: 20 }, in other words, width == 240
|
400
|
+
// We don't need to specify layout.left, layout.right or layout.width, this is automatic.
|
401
|
+
layout: { top: 10, bottom: 10 }
|
402
|
+
|
403
|
+
})
|
404
|
+
|
405
|
+
});
|
406
|
+
|
407
|
+
## Modify specific child view layouts
|
408
|
+
|
409
|
+
To adjust the child layout on a granular level per child view, you can
|
410
|
+
also set the following properties on each child view:
|
411
|
+
|
412
|
+
- marginBefore - Specify the minimum spacing above the child view.
|
413
|
+
- marginAfter - Specify the minimum spacing below the child view.
|
414
|
+
- useAbsoluteLayout - Don't include this child view in automatic layout, use absolute positioning based on the child view's `layout` property.
|
415
|
+
- useStaticLayout - Don't include this child view in automatic layout. This child view uses relative positioning and is not eligible for automatic layout.
|
416
|
+
- isVisible - Non-visible child views are not included in the stack.
|
417
|
+
- fillRatio - When the parent view is configured with a fixed dimension, children not specifying a width but specifying fillRatio will be resized to fill the unclaimed space proportionally to this ratio.
|
418
|
+
|
419
|
+
For example,
|
420
|
+
|
421
|
+
MyApp.MyView = SC.View.extend({
|
422
|
+
|
423
|
+
// Child views will be stacked in order horizontally.
|
424
|
+
childViewLayout: SC.View.HORIZONTAL_STACK,
|
425
|
+
|
426
|
+
// Actual layout will become { left: 10, right: 10, top: 20, width: 570 }
|
427
|
+
layout: { left: 10, right: 10, top: 20 },
|
428
|
+
|
429
|
+
// Keep the child views ordered!
|
430
|
+
childViews: ['sectionA', 'float', 'sectionB', 'sectionC'],
|
431
|
+
|
432
|
+
sectionA: SC.View.design({
|
433
|
+
// Actual layout will become { left: 0, right: 50, top: 0, width: 100 }
|
434
|
+
layout: { right: 50, width: 100 },
|
435
|
+
// The following child view will be at least 50px further right.
|
436
|
+
marginAfter: 50
|
437
|
+
}),
|
438
|
+
|
439
|
+
float: SC.View.design({
|
440
|
+
// This view will not be included in automatic layout and will not effect the stack.
|
441
|
+
layout: { top: 5, right: 5, height: 50, width: 50 },
|
442
|
+
useAbsoluteLayout: true
|
443
|
+
}),
|
444
|
+
|
445
|
+
sectionB: SC.View.design({
|
446
|
+
// Actual layout will become { left: 1500, right: 0, top: 0, width: 120 }
|
447
|
+
layout: { width: 120 }
|
448
|
+
}),
|
449
|
+
|
450
|
+
sectionC: SC.View.design({
|
451
|
+
// Actual layout will become { left: 470, bottom: 0, top: 0, width: 100 }
|
452
|
+
layout: { width: 100 },
|
453
|
+
// This child view will be at least 200px to the right of the previous.
|
454
|
+
marginBefore: 200
|
455
|
+
})
|
456
|
+
|
457
|
+
});
|
458
|
+
|
459
|
+
### A Note About Spacing
|
460
|
+
|
461
|
+
Note that the spacing attribute in `childViewLayoutOptions` becomes the
|
462
|
+
_minimum margin between child views, without explicitly overriding it from
|
463
|
+
both sides using `marginAfter` and `marginBefore`_. For example, if `spacing`
|
464
|
+
is 25, setting `marginAfter` to 10 on a child view will not result in the
|
465
|
+
next child view being 10px to the right of it, unless the next child view also
|
466
|
+
specified `marginBefore` as 10.
|
467
|
+
|
468
|
+
What this means is that it takes less configuration if you set `spacing` to
|
469
|
+
be the _smallest margin you wish to exist between child views_ and then use
|
470
|
+
the overrides to grow the margin if necessary. For example, if `spacing`
|
471
|
+
is 5, setting `marginAfter` to 10 on a child view will result in the next
|
472
|
+
child view being 10px to the right of it, without having to also specify
|
473
|
+
`marginBefore` on that next child view.
|
474
|
+
|
475
|
+
@extends SC.ChildViewLayoutProtocol
|
476
|
+
@since Version 1.10
|
477
|
+
*/
|
478
|
+
HORIZONTAL_STACK: new _SC_VIEW_STACK_PLUGIN('horizontal'),
|
479
|
+
|
480
|
+
/**
|
481
|
+
This child layout plugin automatically positions the view's child views in a
|
482
|
+
vertical stack and optionally adjusts the view's height to fit. It does this
|
483
|
+
by checking the height of each child view and positioning the following child
|
484
|
+
view accordingly. Afterwards, by default, any time that a child view's
|
485
|
+
height or visibility changes, the view will use this plugin to re-adjust all
|
486
|
+
following child views' positions and potentially its own height appropriately.
|
487
|
+
|
488
|
+
This allows you to stack absolutely positioned views that dynamically change
|
489
|
+
their height and/or visibility without having to resort to using browser
|
490
|
+
flow layout.
|
491
|
+
|
492
|
+
A typical usage scenario is a long "form" made of multiple subsection
|
493
|
+
views. If we want to adjust the height of a subsection, to make space for
|
494
|
+
an error label for example, it would be a lot of work to manually
|
495
|
+
reposition all the following sections below it. A much easier to code and
|
496
|
+
cleaner solution is to just set the childViewLayout plugin on the wrapper
|
497
|
+
view.
|
498
|
+
|
499
|
+
For example,
|
500
|
+
|
501
|
+
MyApp.MyView = SC.View.extend({
|
502
|
+
|
503
|
+
// Child views will be stacked in order vertically.
|
504
|
+
childViewLayout: SC.View.VERTICAL_STACK,
|
505
|
+
|
506
|
+
// The order of child views is important!
|
507
|
+
childViews: ['sectionA', 'sectionB', 'sectionC'],
|
508
|
+
|
509
|
+
// The view will resize itself to fit its children.
|
510
|
+
// i.e. We don't need to specify layout.height, this is automatic.
|
511
|
+
// The actual layout will become { left: 10, right: 10, top: 20, height: 270 } initially.
|
512
|
+
layout: { left: 10, right: 10, top: 20 },
|
513
|
+
|
514
|
+
sectionA: SC.View.design({
|
515
|
+
|
516
|
+
// We don't need to specify layout.top, this is automatic.
|
517
|
+
// The actual layout will become { left: 0, right: 0, top: 0, height: 100 } initially.
|
518
|
+
layout: { height: 100 }
|
519
|
+
|
520
|
+
}),
|
521
|
+
|
522
|
+
sectionB: SC.View.design({
|
523
|
+
|
524
|
+
// We don't need to specify layout.top, this is automatic.
|
525
|
+
// The actual layout will become { border: 1, left: 0, right: 0, top: 100, height: 50 } initially.
|
526
|
+
layout: { border: 1, height: 50 }
|
527
|
+
|
528
|
+
}),
|
529
|
+
|
530
|
+
sectionC: SC.View.design({
|
531
|
+
|
532
|
+
// We don't need to specify layout.top, this is automatic.
|
533
|
+
// The actual layout will become { left: 10, right: 10, top: 150, height: 120 } initially.
|
534
|
+
layout: { left: 10, right: 10, height: 120 }
|
535
|
+
|
536
|
+
})
|
537
|
+
|
538
|
+
});
|
539
|
+
|
540
|
+
## Modify the default behavior with `childViewLayoutOptions`
|
541
|
+
|
542
|
+
To modify the plugin behavior for all child view layouts, you can set the
|
543
|
+
following child view layout options in `childViewLayoutOptions` on the view:
|
544
|
+
|
545
|
+
- paddingBefore - Adds padding before the first child view. Default: 0
|
546
|
+
- paddingAfter - Adds padding after the last child view. Default: 0
|
547
|
+
- spacing - Adds spacing between each child view. Default: 0
|
548
|
+
- resizeToFit - Whether to resize the view to fit the child views (requires that each child view has a layout height). Default: true
|
549
|
+
|
550
|
+
For example,
|
551
|
+
|
552
|
+
MyApp.MyView = SC.View.extend({
|
553
|
+
|
554
|
+
// Child views will be stacked in order vertically.
|
555
|
+
childViewLayout: SC.View.VERTICAL_STACK,
|
556
|
+
|
557
|
+
// Change the behavior of the VERTICAL_STACK plugin
|
558
|
+
childViewLayoutOptions: {
|
559
|
+
paddingBefore: 10,
|
560
|
+
paddingAfter: 20,
|
561
|
+
spacing: 5
|
562
|
+
},
|
563
|
+
|
564
|
+
// The order of child views is important!
|
565
|
+
childViews: ['sectionA', 'sectionB', 'sectionC'],
|
566
|
+
|
567
|
+
// The actual layout will become { left: 10, right: 10, top: 20, height: 310 } initially.
|
568
|
+
layout: { left: 10, right: 10, top: 20 }, // Don't need to specify layout.height, this is automatic.
|
569
|
+
|
570
|
+
sectionA: SC.View.design({
|
571
|
+
|
572
|
+
// We don't need to specify layout.top, this is automatic.
|
573
|
+
// The actual layout will become { left: 0, right: 0, top: 10, height: 100 } initially.
|
574
|
+
layout: { height: 100 }
|
575
|
+
|
576
|
+
}),
|
577
|
+
|
578
|
+
sectionB: SC.View.design({
|
579
|
+
|
580
|
+
// We don't need to specify layout.top, this is automatic.
|
581
|
+
// The actual layout will become { border: 1, left: 0, right: 0, top: 115, height: 50 } initially.
|
582
|
+
layout: { border: 1, height: 50 }
|
583
|
+
|
584
|
+
}),
|
585
|
+
|
586
|
+
sectionC: SC.View.design({
|
587
|
+
|
588
|
+
// We don't need to specify layout.top, this is automatic.
|
589
|
+
// The actual layout will become { left: 10, right: 10, top: 170, height: 120 } initially.
|
590
|
+
layout: { left: 10, right: 10, height: 120 }
|
591
|
+
|
592
|
+
})
|
593
|
+
|
594
|
+
});
|
595
|
+
|
596
|
+
If `resizeToFit` is set to `false`, the view will not adjust itself to fit
|
597
|
+
its child views. This means that when `resizeToFit` is false, the view should
|
598
|
+
specify its height component in its layout. A direct effect is the possibility for
|
599
|
+
the child views to automatically extend or shrink in order to fill the empty, unclaimed space.
|
600
|
+
This available space is shared between the children not specifying a fixed height
|
601
|
+
and their final dimension is calculated proportionally to the value of the
|
602
|
+
property `fillRatio`.
|
603
|
+
For simplicity, when none of the children specifies `fillRatio`,
|
604
|
+
you can ignore the last child view's layout height if you want the last child view
|
605
|
+
to stretch to fill the parent view.
|
606
|
+
|
607
|
+
For example,
|
608
|
+
|
609
|
+
MyApp.MyView = SC.View.extend({
|
610
|
+
|
611
|
+
// Child views will be stacked in order vertically.
|
612
|
+
childViewLayout: SC.View.VERTICAL_STACK,
|
613
|
+
|
614
|
+
// Change the behavior of the VERTICAL_STACK plugin
|
615
|
+
childViewLayoutOptions: {
|
616
|
+
paddingBefore: 10,
|
617
|
+
paddingAfter: 20,
|
618
|
+
spacing: 5,
|
619
|
+
resizeToFit: false
|
620
|
+
},
|
621
|
+
|
622
|
+
// The order of child views is important!
|
623
|
+
childViews: ['sectionA', 'sectionB', 'sectionC'],
|
624
|
+
|
625
|
+
// Actual layout will become { left: 10, right: 10, top: 20, height: 500 }
|
626
|
+
layout: { left: 10, right: 10, top: 20, height: 500 }, // Need to specify layout.height.
|
627
|
+
|
628
|
+
sectionA: SC.View.design({
|
629
|
+
|
630
|
+
// We don't need to specify layout.top, this is automatic. This child will not stretch, its height is set.
|
631
|
+
// The actual layout will become { left: 0, right: 0, top: 10, height: 100 } initially.
|
632
|
+
layout: { height: 100 }
|
633
|
+
|
634
|
+
}),
|
635
|
+
|
636
|
+
sectionB: SC.View.design({
|
637
|
+
|
638
|
+
// The unclaimed space so far is 500 - 10 - 100 - 5 - 5 - 20, or 360px. This space will be shared between
|
639
|
+
// the two last sections, because we won't specity a height on them.
|
640
|
+
// This view will get 1/3 of the available space, because the other flexibile view has a ratio of 2.
|
641
|
+
fillRatio: 1,
|
642
|
+
|
643
|
+
// This section will take 1/3 * 360px = 120px.
|
644
|
+
// Actual layout will become { border: 1, left: 0, right: 0, top: 115, bottom: 265 }, in other words, height == 120
|
645
|
+
// We don't need to specify layout.top, layout.bottom or layout.height, this is automatic.
|
646
|
+
layout: { border: 1 }
|
647
|
+
|
648
|
+
}),
|
649
|
+
|
650
|
+
sectionC: SC.View.design({
|
651
|
+
|
652
|
+
// This view will get 2/3 of the available space, because the other flexibile view has a ratio of 1.
|
653
|
+
fillRatio: 2,
|
654
|
+
|
655
|
+
// This section will take 2/3 * 360px = 240px.
|
656
|
+
// Actual layout will become { left: 10, right: 10, top: 240, bottom: 20 }, in other words, height == 240
|
657
|
+
// We don't need to specify layout.top, layout.bottom or layout.height, this is automatic.
|
658
|
+
layout: { left: 10, right: 10 }
|
659
|
+
|
660
|
+
})
|
661
|
+
|
662
|
+
});
|
663
|
+
|
664
|
+
## Modify specific child view layouts
|
665
|
+
|
666
|
+
To adjust the child layout on a granular level per child view, you can
|
667
|
+
also set the following properties on each child view:
|
668
|
+
|
669
|
+
- marginBefore - Specify the minimum spacing above the child view.
|
670
|
+
- marginAfter - Specify the minimum spacing below the child view.
|
671
|
+
- useAbsoluteLayout - Don't include this child view in automatic layout, use absolute positioning based on the child view's `layout` property.
|
672
|
+
- useStaticLayout - Don't include this child view in automatic layout. This child view uses relative positioning and is not eligible for automatic layout.
|
673
|
+
- isVisible - Non-visible child views are not included in the stack.
|
674
|
+
- fillRatio - When the parent view is configured with a fixed dimension, children not specifying a height but specifying fillRatio will be resized to fill the unclaimed space proportionally to this ratio.
|
675
|
+
|
676
|
+
For example,
|
677
|
+
|
678
|
+
MyApp.MyView = SC.View.extend({
|
679
|
+
|
680
|
+
// Child views will be stacked in order vertically.
|
681
|
+
childViewLayout: SC.View.VERTICAL_STACK,
|
682
|
+
|
683
|
+
// Actual layout will become { left: 10, right: 10, top: 20, height: 570 }
|
684
|
+
layout: { left: 10, right: 10, top: 20 },
|
685
|
+
|
686
|
+
// Keep the child views ordered!
|
687
|
+
childViews: ['sectionA', 'float', 'sectionB', 'sectionC'],
|
688
|
+
|
689
|
+
sectionA: SC.View.design({
|
690
|
+
// Actual layout will become { left: 0, right: 50, top: 0, height: 100 }
|
691
|
+
layout: { right: 50, height: 100 },
|
692
|
+
// The following child view will be at least 50px further down.
|
693
|
+
marginAfter: 50
|
694
|
+
}),
|
695
|
+
|
696
|
+
float: SC.View.design({
|
697
|
+
// This view will not be included in automatic layout and will not effect the stack.
|
698
|
+
layout: { top: 5, right: 5, width: 50, height: 50 },
|
699
|
+
useAbsoluteLayout: true
|
700
|
+
}),
|
701
|
+
|
702
|
+
sectionB: SC.View.design({
|
703
|
+
// Actual layout will become { left: 0, right: 0, top: 150, height: 120 }
|
704
|
+
layout: { height: 120 }
|
705
|
+
}),
|
706
|
+
|
707
|
+
sectionC: SC.View.design({
|
708
|
+
// Actual layout will become { left: 0, bottom: 0, top: 470, height: 100 }
|
709
|
+
layout: { height: 100 },
|
710
|
+
// This child view will be at least 200px below the previous.
|
711
|
+
marginBefore: 200
|
712
|
+
})
|
713
|
+
|
714
|
+
});
|
715
|
+
|
716
|
+
### A Note About Spacing
|
717
|
+
|
718
|
+
Note that the spacing attribute in `childViewLayoutOptions` becomes the
|
719
|
+
_minimum margin between child views, without explicitly overriding it from
|
720
|
+
both sides using `marginAfter` and `marginBefore`_. For example, if `spacing`
|
721
|
+
is 25, setting `marginAfter` to 10 on a child view will not result in the
|
722
|
+
next child view being 10px below it, unless the next child view also
|
723
|
+
specified `marginBefore` as 10.
|
724
|
+
|
725
|
+
What this means is that it takes less configuration if you set `spacing` to
|
726
|
+
be the _smallest margin you wish to exist between child views_ and then use
|
727
|
+
the overrides to grow the margin if necessary. For example, if `spacing`
|
728
|
+
is 5, setting `marginAfter` to 10 on a child view will result in the next
|
729
|
+
child view being 10px below it, without having to also specify `marginBefore`
|
730
|
+
on that next child view.
|
731
|
+
|
732
|
+
@extends SC.ChildViewLayoutProtocol
|
733
|
+
@since Version 1.10
|
734
|
+
*/
|
735
|
+
VERTICAL_STACK: new _SC_VIEW_STACK_PLUGIN('vertical')
|
736
|
+
|
737
|
+
});
|