bm-core-ui 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1624 -0
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/build/@types/index.d.ts +14078 -0
- package/build/BMCodeEditor/BMCodeEditor.js +707 -0
- package/build/BMCollectionView/BMCollectionView.js +5861 -0
- package/build/BMCollectionView/BMCollectionViewCell.js +688 -0
- package/build/BMCollectionView/BMCollectionViewFlowLayout.js +4467 -0
- package/build/BMCollectionView/BMCollectionViewLayout.js +830 -0
- package/build/BMCollectionView/BMCollectionViewLayoutAttributes.js +673 -0
- package/build/BMCollectionView/BMCollectionViewMasonryLayout.js +491 -0
- package/build/BMCollectionView/BMCollectionViewStackLayout.js +634 -0
- package/build/BMCollectionView/BMCollectionViewTileLayout.js +1121 -0
- package/build/BMCoreUI.css +2833 -0
- package/build/BMView/BMAttributedLabelView.js +310 -0
- package/build/BMView/BMLayoutConstraint_v2.5.js +1813 -0
- package/build/BMView/BMLayoutGuide.js +192 -0
- package/build/BMView/BMLayoutSizeClass.js +466 -0
- package/build/BMView/BMMenu.js +574 -0
- package/build/BMView/BMScrollView.js +247 -0
- package/build/BMView/BMTextField.js +512 -0
- package/build/BMView/BMTextFieldDelegate.js +71 -0
- package/build/BMView/BMView_v2.5.js +3572 -0
- package/build/BMView/BMViewport.js +221 -0
- package/build/BMViewLayoutEditor/BMLayoutEditor.js +6117 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorConstraintSettings.js +417 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorDelegate.js +59 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingCells.js +1653 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorSettings.js +1480 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingsComplexCells.js +431 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingsDelegate.js +46 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorVariablesController.js +460 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorViewGroupSettings.js +293 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorViewSettings.js +382 -0
- package/build/BMViewLayoutEditor/BMLayoutVariableProvider.js +202 -0
- package/build/BMWindow/BMConfirmationPopup.js +477 -0
- package/build/BMWindow/BMKeyboardShortcut.js +151 -0
- package/build/BMWindow/BMPopover/BMPopover.js +492 -0
- package/build/BMWindow/BMToolWindow.js +71 -0
- package/build/BMWindow/BMWindow.js +2000 -0
- package/build/Core/BMAnimationContext.js +1181 -0
- package/build/Core/BMColor.js +991 -0
- package/build/Core/BMCoreUI.js +470 -0
- package/build/Core/BMFunctionCollection.js +110 -0
- package/build/Core/BMIndexPath.js +165 -0
- package/build/Core/BMInset.js +138 -0
- package/build/Core/BMKeyPath.js +100 -0
- package/build/Core/BMPoint.js +291 -0
- package/build/Core/BMRect.js +556 -0
- package/build/Core/BMSize.js +137 -0
- package/build/iScroll/LICENSE +22 -0
- package/build/iScroll/iscroll-probe.js +2154 -0
- package/build/images/AlignBottom.png +0 -0
- package/build/images/AlignCenterX.png +0 -0
- package/build/images/AlignCenterY.png +0 -0
- package/build/images/AlignLeading.png +0 -0
- package/build/images/AlignTop.png +0 -0
- package/build/images/AlignTrailing.png +0 -0
- package/build/images/AllConstraints.png +0 -0
- package/build/images/BottomConstraint.png +0 -0
- package/build/images/CenterXConstraint.png +0 -0
- package/build/images/CenterYConstraint.png +0 -0
- package/build/images/CoreUI2.png +0 -0
- package/build/images/CoreUI2@2x.png +0 -0
- package/build/images/Desktop.png +0 -0
- package/build/images/DesktopMini.png +0 -0
- package/build/images/EqualHeight.png +0 -0
- package/build/images/EqualHorizontalSpacing.png +0 -0
- package/build/images/EqualHorizontalSpacingInSuperview.png +0 -0
- package/build/images/EqualVerticalSpacing.png +0 -0
- package/build/images/EqualVerticalSpacingInSuperview.png +0 -0
- package/build/images/EqualWidth.png +0 -0
- package/build/images/HeightConstraint.png +0 -0
- package/build/images/InactiveConstraints.png +0 -0
- package/build/images/Layout.png +0 -0
- package/build/images/LayoutVariables.png +0 -0
- package/build/images/LeftConstraint.png +0 -0
- package/build/images/OwnConstraints.png +0 -0
- package/build/images/Phone.png +0 -0
- package/build/images/PhoneLandscape.png +0 -0
- package/build/images/PhoneLandscapeMini.png +0 -0
- package/build/images/PhoneMini.png +0 -0
- package/build/images/PhonePortrait.png +0 -0
- package/build/images/PhonePortraitMini.png +0 -0
- package/build/images/Properties.png +0 -0
- package/build/images/RightConstraint.png +0 -0
- package/build/images/SubviewConstraints.png +0 -0
- package/build/images/Tablet.png +0 -0
- package/build/images/TabletLandscape.png +0 -0
- package/build/images/TabletLandscapeMini.png +0 -0
- package/build/images/TabletMini.png +0 -0
- package/build/images/TabletPortrait.png +0 -0
- package/build/images/TabletPortraitMini.png +0 -0
- package/build/images/TopConstraint.png +0 -0
- package/build/images/WidthConstraint.png +0 -0
- package/build/index.js +40 -0
- package/lib/@types/BMCoreUI.min.d.ts +14078 -0
- package/lib/BMCoreUI.min.js +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {YES, NO, BMCopyProperties, BMExtend, BMNumberByInterpolatingNumbersWithFraction} from '../Core/BMCoreUI'
|
|
4
|
+
import {BMPointMake} from '../Core/BMPoint'
|
|
5
|
+
import {BMRectMakeWithOrigin, BMRectByInterpolatingRect} from '../Core/BMRect'
|
|
6
|
+
import {BMAnimationContextGetCurrent, BMHook} from '../Core/BMAnimationContext'
|
|
7
|
+
|
|
8
|
+
// @type BMCollectionViewLayoutAttributesType
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The type of view an attributes object applies to.
|
|
12
|
+
* This enumeration is also used by cell objects to make it possible to identify their type.
|
|
13
|
+
*/
|
|
14
|
+
export var BMCollectionViewLayoutAttributesType = Object.freeze({ // <enum>
|
|
15
|
+
/**
|
|
16
|
+
* Indicates that these attributes apply to cells.
|
|
17
|
+
*/
|
|
18
|
+
Cell: {}, // <enum>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Indicates that these attributes apply to supplementary views.
|
|
22
|
+
*/
|
|
23
|
+
SupplementaryView: {}, // <enum>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Indicates that these attributes apply to decoration views.
|
|
27
|
+
* Decoration views are a planned feature - currently this value should not be used.
|
|
28
|
+
*/
|
|
29
|
+
DecorationView: {} // <enum>
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated Deprecated. Use BMCollectionViewCellAttributesType instead.
|
|
34
|
+
*/
|
|
35
|
+
export var BMCellAttributesType = BMCollectionViewLayoutAttributesType; // <enum>
|
|
36
|
+
|
|
37
|
+
// @endtype
|
|
38
|
+
|
|
39
|
+
// These default values are used when applying a new style that doesn't contain all of the properties of the previous style.
|
|
40
|
+
// In that case, each missing property will be added to the new style with the value from this list.
|
|
41
|
+
/* @private */ export var BMCollectionViewLayoutAttributesStyleDefaults = Object.freeze({
|
|
42
|
+
opacity: 1,
|
|
43
|
+
scaleX: 1,
|
|
44
|
+
scaleY: 1,
|
|
45
|
+
rotate: 0,
|
|
46
|
+
rotateX: 0,
|
|
47
|
+
rotateY: 0,
|
|
48
|
+
rotateZ: 0,
|
|
49
|
+
skewX: 0,
|
|
50
|
+
skewY: 0,
|
|
51
|
+
skewZ: 0,
|
|
52
|
+
transformOriginX: '50%',
|
|
53
|
+
transformOriginY: '50%',
|
|
54
|
+
translateZ: 0,
|
|
55
|
+
blur: '0px'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// @deprecated
|
|
59
|
+
var BMCellAttributesStyleDefaults = BMCollectionViewLayoutAttributesStyleDefaults;
|
|
60
|
+
|
|
61
|
+
// @type BMCollectionViewLayoutAttributes
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Manages the layout attributes for a cell or supplementary view. The cell attributes will automatically apply themselves to a cell's
|
|
65
|
+
* DOM element whenever they are assigned to a cell. Additionally, the attributes are also animatable. Applying attributes, frames or styles while there
|
|
66
|
+
* is an active animation context will cause that change to be animated.
|
|
67
|
+
*
|
|
68
|
+
* Cell attributes should not be created using the constructor; instead one of the BMCollectionViewCellAttributesMake... functions should be used to obtain new instances.
|
|
69
|
+
*/
|
|
70
|
+
export function BMCollectionViewLayoutAttributes() {}; // <constructor>
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @deprecated Deprecated. Use BMCollectionViewCellAttributes instead.
|
|
74
|
+
*/
|
|
75
|
+
var BMCellAttributes = BMCollectionViewLayoutAttributes; // <Class extends BMCollectionViewLayoutAttributes>
|
|
76
|
+
|
|
77
|
+
BMCollectionViewLayoutAttributes.prototype = {
|
|
78
|
+
/**
|
|
79
|
+
* The cell whose layout is managed by these attributes.
|
|
80
|
+
*/
|
|
81
|
+
_cell: undefined, // <BMCollectionViewCell, nullable>
|
|
82
|
+
|
|
83
|
+
get cell() {
|
|
84
|
+
return this._cell;
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
set cell(cell) {
|
|
88
|
+
this._cell = cell;
|
|
89
|
+
|
|
90
|
+
if (cell && cell.element) {
|
|
91
|
+
// Only apply the new frame if it is different or if the cell is transitioning from being collected, to avoid having to set up unnecessary animations.
|
|
92
|
+
if (!cell._previousFrame || !cell._previousFrame.isEqualToRect(this.frame) || !cell.retainCount) {
|
|
93
|
+
this._hookFrame();
|
|
94
|
+
}
|
|
95
|
+
// Same for the style
|
|
96
|
+
if (this._style && Object.keys(this._style).length) {
|
|
97
|
+
// TODO Separate frame attributes
|
|
98
|
+
this._style.translateX = this.frame.origin.x + 'px';
|
|
99
|
+
this._style.translateY = this.frame.origin.y + 'px';
|
|
100
|
+
this.hook(this._style);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The type of item these attributes apply to.
|
|
107
|
+
*/
|
|
108
|
+
_itemType: BMCollectionViewLayoutAttributesType.Cell, // <BMCollectionViewLayoutAttributesType>
|
|
109
|
+
|
|
110
|
+
get itemType() { return this._itemType; },
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The item kind for supplementary and decoration views.
|
|
114
|
+
*/
|
|
115
|
+
identifier: undefined, // <String>
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The position of the cell in the layout.
|
|
119
|
+
*/
|
|
120
|
+
_frame: undefined, // <BMRect>
|
|
121
|
+
|
|
122
|
+
get frame() {
|
|
123
|
+
return this._frame;
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
set frame(frame) {
|
|
127
|
+
this._frame = frame.copy();
|
|
128
|
+
this._hookFrame();
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Generates and applies the hook properties for the frame.
|
|
133
|
+
*/
|
|
134
|
+
_hookFrame: function () {
|
|
135
|
+
var frame = this.frame;
|
|
136
|
+
|
|
137
|
+
if (this._cell && this._cell.element) {
|
|
138
|
+
var hookProperties = {
|
|
139
|
+
translateX: frame.origin.x + 'px',
|
|
140
|
+
translateY: frame.origin.y + 'px'
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (this._cell._lastAssignedWidth != frame.size.width) {
|
|
144
|
+
hookProperties.width = frame.size.width + 'px';
|
|
145
|
+
}
|
|
146
|
+
if (this._cell._lastAssignedHeight != frame.size.height) {
|
|
147
|
+
hookProperties.height = frame.size.height + 'px';
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// If applying the frame causes a size change, notify the delegate.
|
|
151
|
+
if (hookProperties.width || hookProperties.height) {
|
|
152
|
+
if (this._cell.collectionView.delegate && this._cell.collectionView.delegate.collectionViewWillResizeCell) {
|
|
153
|
+
this._cell.collectionView.delegate.collectionViewWillResizeCell(this._cell.collectionView, this._cell, {toSize: frame.size.copy()});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
this.hook(hookProperties);
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Invoked by the collection view to flatten the cell using these attributes prior to an animated release.
|
|
164
|
+
* This will cause any transform or opacity styles to be removed from the cell, which may affect the fidelity
|
|
165
|
+
* of the resulting layer.
|
|
166
|
+
*/
|
|
167
|
+
_flatten: function () {
|
|
168
|
+
// Unassigned attributes cannot be flattened
|
|
169
|
+
if (!this._cell) return;
|
|
170
|
+
|
|
171
|
+
// Destroy any transform styles
|
|
172
|
+
this.style = {};
|
|
173
|
+
this._cell.element[0].style.transform = '';
|
|
174
|
+
|
|
175
|
+
// Hook the frame, using left/right instead of translations
|
|
176
|
+
// The correct sizing should already be applied, so there is no need to reapply it here
|
|
177
|
+
BMCopyProperties(this._cell.element[0].style, {left: this._frame.origin.x + 'px', top: this._frame.origin.y + 'px'});
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* The cell's style and transform attributes
|
|
182
|
+
*/
|
|
183
|
+
_style: undefined, // <Object, nullResettable>
|
|
184
|
+
|
|
185
|
+
get style() {
|
|
186
|
+
if (!this._style) this._style = {};
|
|
187
|
+
return this._style;
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
set style(style) {
|
|
191
|
+
style = style || {};
|
|
192
|
+
|
|
193
|
+
// Remove the forbidden values
|
|
194
|
+
delete style.width;
|
|
195
|
+
delete style.height;
|
|
196
|
+
delete style.left;
|
|
197
|
+
delete style.right;
|
|
198
|
+
delete style.translateX;
|
|
199
|
+
delete style.translateY;
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
var oldStyle = this._style;
|
|
203
|
+
|
|
204
|
+
// Always copy style objects, never assign directly
|
|
205
|
+
// TODO Separate frame attributes
|
|
206
|
+
this._style = {
|
|
207
|
+
translateX: this.frame.origin.x + 'px',
|
|
208
|
+
translateY: this.frame.origin.y + 'px'
|
|
209
|
+
};
|
|
210
|
+
for (key in style) {
|
|
211
|
+
this._style[key] = style[key];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Clear the old attributes
|
|
215
|
+
if (oldStyle) for (var key in oldStyle) {
|
|
216
|
+
if (style[key] === undefined) style[key] = BMCollectionViewLayoutAttributesStyleDefaults[key];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
this.hook(style);
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Applies the specified style on top of the current style properties.
|
|
224
|
+
* @param style <Object> The list of properties to apply to the UI element.
|
|
225
|
+
*/
|
|
226
|
+
addStyle: function(style) {
|
|
227
|
+
|
|
228
|
+
// Remove the forbidden values
|
|
229
|
+
|
|
230
|
+
delete style.width;
|
|
231
|
+
delete style.height;
|
|
232
|
+
delete style.left;
|
|
233
|
+
delete style.right;
|
|
234
|
+
delete style.translateX;
|
|
235
|
+
delete style.translateY;
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
for (var key in style) {
|
|
239
|
+
this._style[key] = style[key];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
this.hook(style);
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Determines whether the cell using these attributes is hidden.
|
|
247
|
+
* When cells are marked as hidden, the collection view may skip rendering them entirely.
|
|
248
|
+
*/
|
|
249
|
+
_isHidden: NO, // <Boolean>
|
|
250
|
+
|
|
251
|
+
get isHidden() { return this._isHidden; },
|
|
252
|
+
set isHidden(hidden) {
|
|
253
|
+
this._isHidden = hidden;
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Applies the given hook properties to the backing UI element, if it is available.
|
|
258
|
+
* If the UI element is not available, these properties will be applied when it becomes available.
|
|
259
|
+
* @param properties <Object> The list of properties to apply to the UI element.
|
|
260
|
+
* This object should not contain position or size attributes; these should be controlled through the frame property instead.
|
|
261
|
+
*/
|
|
262
|
+
hook: function (properties) {
|
|
263
|
+
if (!this._cell || !this._cell.element) return;
|
|
264
|
+
|
|
265
|
+
var self = this;
|
|
266
|
+
|
|
267
|
+
if (BMAnimationContextGetCurrent()) {
|
|
268
|
+
var animation = BMAnimationContextGetCurrent();
|
|
269
|
+
|
|
270
|
+
var subscriber = animation.subscribers.get(this);
|
|
271
|
+
|
|
272
|
+
// If the cell's hidden state doesn't match the attributes and the attributes are visible, make the cell visible
|
|
273
|
+
if (this._cell._isHidden != this._isHidden && !this._isHidden) {
|
|
274
|
+
this._cell.isHidden = NO;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (!subscriber) {
|
|
278
|
+
subscriber = {
|
|
279
|
+
prepare() {
|
|
280
|
+
if (!self._cell) return;
|
|
281
|
+
|
|
282
|
+
// merge the property maps
|
|
283
|
+
var propertyMap = {};
|
|
284
|
+
|
|
285
|
+
for (var i = 0; i < this.properties.length; i++) {
|
|
286
|
+
var map = this.properties[i];
|
|
287
|
+
for (var key in map) {
|
|
288
|
+
|
|
289
|
+
propertyMap[key] = map[key];
|
|
290
|
+
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
this._propertyMap = propertyMap;
|
|
295
|
+
|
|
296
|
+
// If applying the properties will cause a size change, allow the cell to react.
|
|
297
|
+
if (properties.width || properties.height) {
|
|
298
|
+
var bounds = BMRectMakeWithOrigin(BMPointMake(), {size: self.frame.size.copy()});
|
|
299
|
+
self._cell.boundsWillChangeToBounds(bounds);
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
//
|
|
304
|
+
// The apply method is invoked by the animation engine when the animation is applied.
|
|
305
|
+
// The subscribers should use this method to finish preparing their target and properties attributes for the animation.
|
|
306
|
+
// @param animation <BMAnimation> The animation object.
|
|
307
|
+
//
|
|
308
|
+
apply: function (animation) {
|
|
309
|
+
if (!self._cell) return;
|
|
310
|
+
var propertyMap = this._propertyMap;
|
|
311
|
+
|
|
312
|
+
var cell = self._cell;
|
|
313
|
+
let resolveAnimation;
|
|
314
|
+
cell._layoutAnimator = new Promise($0 => resolveAnimation = $0);
|
|
315
|
+
|
|
316
|
+
var oldBounds = self._cell._bounds;
|
|
317
|
+
var boundsWillChange = NO;
|
|
318
|
+
var newBounds;
|
|
319
|
+
|
|
320
|
+
// If applying the properties will cause a size change, allow the cell to react.
|
|
321
|
+
if (properties.width || properties.height) {
|
|
322
|
+
var bounds = BMRectMakeWithOrigin(BMPointMake(), {size: self.frame.size.copy()});
|
|
323
|
+
boundsWillChange = YES;
|
|
324
|
+
//propertyMap.tween = 1;
|
|
325
|
+
newBounds = bounds.copy();
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
var complete = NO;
|
|
329
|
+
var targetWidth = self.frame.size.width;
|
|
330
|
+
var targetHeight = self.frame.size.height;
|
|
331
|
+
|
|
332
|
+
let progressCallback = boundsWillChange && oldBounds ? ($0, $1, $2, $3, fraction) => {
|
|
333
|
+
let intermediateBounds = oldBounds.interpolatedValueWithFraction(fraction, {toValue: newBounds});
|
|
334
|
+
cell.boundsDidTransitionToBounds(intermediateBounds);
|
|
335
|
+
} : undefined;
|
|
336
|
+
|
|
337
|
+
animation.targets.push({element: self._cell.element[0], properties: propertyMap, complete: function () {
|
|
338
|
+
if (complete) return;
|
|
339
|
+
complete = YES;
|
|
340
|
+
|
|
341
|
+
if (propertyMap.width) {
|
|
342
|
+
cell._lastAssignedWidth = targetWidth;
|
|
343
|
+
}
|
|
344
|
+
if (propertyMap.height) {
|
|
345
|
+
cell._lastAssignedHeight = targetHeight;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// If the cell's hidden state doesn't match the attributes and the attributes are hidden, make the cell hidden
|
|
349
|
+
if (cell._isHidden != self._isHidden && self._isHidden) {
|
|
350
|
+
cell.isHidden = YES;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
resolveAnimation();
|
|
354
|
+
cell._layoutAnimator = undefined;
|
|
355
|
+
|
|
356
|
+
// If applying the properties caused a size change, notify the delegate.
|
|
357
|
+
if (properties.width || properties.height) {
|
|
358
|
+
|
|
359
|
+
// Compute and apply the new bounds
|
|
360
|
+
var bounds = BMRectMakeWithOrigin(BMPointMake(), {size: self.frame.size.copy()});
|
|
361
|
+
var oldBounds = cell._bounds;
|
|
362
|
+
cell._bounds = bounds;
|
|
363
|
+
cell.boundsDidChangeFromBounds(oldBounds);
|
|
364
|
+
|
|
365
|
+
// Notify the delegate
|
|
366
|
+
if (cell.collectionView.delegate && cell.collectionView.delegate.collectionViewDidResizeCell) {
|
|
367
|
+
cell.collectionView.delegate.collectionViewDidResizeCell(cell.collectionView, cell, {toSize: self.frame.size.copy()});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}});
|
|
371
|
+
|
|
372
|
+
},
|
|
373
|
+
properties: []
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
animation.subscribers.set(this, subscriber);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
subscriber.properties.push(properties);
|
|
380
|
+
|
|
381
|
+
// Invalidate the cell's layout if this change would cause the size to change
|
|
382
|
+
if (properties.width || properties.height) {
|
|
383
|
+
self._cell.needsLayout = YES;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
|
|
389
|
+
BMHook(this._cell.element[0], properties);
|
|
390
|
+
|
|
391
|
+
if (properties.width) this._cell._lastAssignedWidth = this.frame.size.width;
|
|
392
|
+
if (properties.height) this._cell._lastAssignedHeight = this.frame.size.height;
|
|
393
|
+
|
|
394
|
+
// If applying the properties caused a size change, notify the delegate.
|
|
395
|
+
if (properties.width || properties.height) {
|
|
396
|
+
// Don't request additional layout passes for transition attributes
|
|
397
|
+
if (!this._fraction) self._cell.needsLayout = YES;
|
|
398
|
+
|
|
399
|
+
// Compute and apply the new bounds
|
|
400
|
+
var bounds = BMRectMakeWithOrigin(BMPointMake(), {size: this.frame.size.copy()});
|
|
401
|
+
this._cell.boundsWillChangeToBounds(bounds);
|
|
402
|
+
var oldBounds = this._cell._bounds;
|
|
403
|
+
this._cell._bounds = bounds;
|
|
404
|
+
this._cell.boundsDidChangeFromBounds(oldBounds);
|
|
405
|
+
|
|
406
|
+
// Notify the delegate
|
|
407
|
+
if (this._cell.collectionView.delegate && this._cell.collectionView.delegate.collectionViewDidResizeCell) {
|
|
408
|
+
this._cell.collectionView.delegate.collectionViewDidResizeCell(this._cell.collectionView, this._cell, {toSize: this.frame.size.copy()});
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Change the cell's visibility to match the attributes
|
|
413
|
+
if (this._isHidden != this._cell._isHidden) {
|
|
414
|
+
this._cell.isHidden = this._isHidden;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* The index path of the model object backing this cell.
|
|
422
|
+
*/
|
|
423
|
+
indexPath: undefined, // <BMIndexPath>
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Creates a new instance of this attributes collection with the same properties as this instance.
|
|
427
|
+
* The new <code>BMCollectionViewLayoutAttributes</code> instance will not be bound to any cell.
|
|
428
|
+
* @return <BMCollectionViewLayoutAttributes> A properties collection instance.
|
|
429
|
+
*/
|
|
430
|
+
copy: function () {
|
|
431
|
+
var attributes = new BMCollectionViewLayoutAttributes();
|
|
432
|
+
attributes._frame = this._frame.copy();
|
|
433
|
+
attributes.indexPath = this.indexPath.copy();
|
|
434
|
+
attributes._style = BMCopyProperties({}, this._style);
|
|
435
|
+
attributes._itemType = this._itemType;
|
|
436
|
+
attributes.identifier = this.identifier;
|
|
437
|
+
return attributes;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Creates and returns a new instance of <code>BMCollectionViewLayoutAttributes</code> for the object at the specified index path.
|
|
443
|
+
* @param indexPath <BMIndexPath> The index path.
|
|
444
|
+
* @return <BMCollectionViewLayoutAttributes> The layout attributes.
|
|
445
|
+
*/
|
|
446
|
+
export function BMCollectionViewLayoutAttributesMakeForCellAtIndexPath(indexPath) {
|
|
447
|
+
var attributes = new BMCollectionViewLayoutAttributes();
|
|
448
|
+
attributes.indexPath = indexPath;
|
|
449
|
+
attributes._itemType = BMCollectionViewLayoutAttributesType.Cell;
|
|
450
|
+
attributes._style = {};
|
|
451
|
+
return attributes;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* @deprecated Deprecated. Use <code>BMCollectionViewLayoutAttributesMakeForCellAtIndexPath</code> instead.
|
|
456
|
+
*/
|
|
457
|
+
var BMCellAttributesMakeForCellAtIndexPath = BMCollectionViewLayoutAttributesMakeForCellAtIndexPath; // <Function>
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Creates and returns a new instance of <code>BMCollectionViewLayoutAttributes</code> for the object at the specified index path.
|
|
461
|
+
* @param identifier <String> The kind of supplementary view.
|
|
462
|
+
* {
|
|
463
|
+
* @param atIndexPath <BMIndexPath> The index path.
|
|
464
|
+
* }
|
|
465
|
+
* @return <BMCollectionViewLayoutAttributes> The cell attributes.
|
|
466
|
+
*/
|
|
467
|
+
export function BMCollectionViewLayoutAttributesMakeForSupplementaryViewWithIdentifier(identifier, options) {
|
|
468
|
+
var attributes = new BMCollectionViewLayoutAttributes();
|
|
469
|
+
attributes.indexPath = options.atIndexPath;
|
|
470
|
+
attributes._itemType = BMCollectionViewLayoutAttributesType.SupplementaryView;
|
|
471
|
+
attributes.identifier = identifier;
|
|
472
|
+
attributes._style = {};
|
|
473
|
+
return attributes;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* @deprecated Deprecated. Use <code>BMCollectionViewLayoutAttributesMakeForSupplementaryViewWithIdentifier</code> instead.
|
|
478
|
+
*/
|
|
479
|
+
var BMCellAttributesMakeForSupplementaryViewWithIdentifier = BMCollectionViewLayoutAttributesMakeForSupplementaryViewWithIdentifier;
|
|
480
|
+
|
|
481
|
+
// @endtype
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
// @type _BMCollectionViewTransitionLayoutAttributes
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* The regex used to extract the units from style CSS values.
|
|
488
|
+
*/
|
|
489
|
+
var _BMCollectionViewTransitionLayoutAttributesUnitRegex = /\-?\+?\d*\.?\d*(\D*)/; // <RegExp>
|
|
490
|
+
|
|
491
|
+
var _BMCollectionViewTransitionCellAttributesUnitRegex = _BMCollectionViewTransitionLayoutAttributesUnitRegex;
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* A specialized version of cell attributes that manages the transition of a cell from one set of attributes to another.
|
|
495
|
+
* The source and target attributes should have the same index path and item type.
|
|
496
|
+
* Transition attributes should not be created and used directly. A collection view will automatically create, manage and destroy transition attributes
|
|
497
|
+
* to perform various animations such as animated layout changes.
|
|
498
|
+
*
|
|
499
|
+
* Transition attributes are created automatically by the collection view when changing layouts with an animation.
|
|
500
|
+
*/
|
|
501
|
+
export function _BMCollectionViewTransitionLayoutAttributes() {}; // <constructor>
|
|
502
|
+
|
|
503
|
+
_BMCollectionViewTransitionLayoutAttributes.prototype = BMExtend({}, BMCollectionViewLayoutAttributes.prototype, {
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* The attributes from which the transition starts.
|
|
507
|
+
*/
|
|
508
|
+
_sourceAttributes: undefined, //<BMCollectionViewLayoutAttributes>
|
|
509
|
+
get sourceAttributes() { return this._sourceAttributes; },
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* The attributes to which the transition moves.
|
|
513
|
+
*/
|
|
514
|
+
_targetAttributes: undefined, //<BMCollectionViewLayoutAttributes>
|
|
515
|
+
get targetAttributes() { return this._targetAttributes; },
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Controls how close the transition is to completion.
|
|
519
|
+
* A value of 0 should correspond to the source attributes while a value of 1 should correspond to the target attributes.
|
|
520
|
+
* Assigning this value will update the target cell.
|
|
521
|
+
*/
|
|
522
|
+
_fraction: 0, // <Number>
|
|
523
|
+
get fraction() { return this._fraction; },
|
|
524
|
+
set fraction(fraction) {
|
|
525
|
+
// set the isHidden property based on the values of the source and target attributes
|
|
526
|
+
if (!this._sourceAttributes.isHidden || !this._targetAttributes.isHidden) {
|
|
527
|
+
this.isHidden = NO;
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
this.isHidden = YES;
|
|
531
|
+
}
|
|
532
|
+
// let isHidden = this._sourceAttributes.isHidden;
|
|
533
|
+
// if (this._targetAttributes != isHidden) {
|
|
534
|
+
// if (fraction != 0 && fraction != 1) {
|
|
535
|
+
// isHidden = NO;
|
|
536
|
+
// }
|
|
537
|
+
// else if (fraction == 0) {
|
|
538
|
+
// isHidden = this._sourceAttributes.isHidden;
|
|
539
|
+
// }
|
|
540
|
+
// else {
|
|
541
|
+
// isHidden = this._targetAttributes.isHidden;
|
|
542
|
+
// }
|
|
543
|
+
// }
|
|
544
|
+
|
|
545
|
+
// this.isHidden = isHidden;
|
|
546
|
+
|
|
547
|
+
this._fraction = fraction;
|
|
548
|
+
|
|
549
|
+
// Update the frame
|
|
550
|
+
this._frame = BMRectByInterpolatingRect(this._sourceAttributes._frame, {toRect: this._targetAttributes._frame, withFraction: fraction});
|
|
551
|
+
this._hookFrame();
|
|
552
|
+
|
|
553
|
+
// Update the style
|
|
554
|
+
var sourceStyle = BMCopyProperties(this._sourceAttributes.style, {translateX: this._sourceAttributes._frame.origin.x + 'px', translateY: this._sourceAttributes._frame.origin.y + 'px'});
|
|
555
|
+
var targetStyle = BMCopyProperties(this._targetAttributes.style, {translateX: this._targetAttributes._frame.origin.x + 'px', translateY: this._targetAttributes._frame.origin.y + 'px'});
|
|
556
|
+
|
|
557
|
+
if (!this._style) this._style = {};
|
|
558
|
+
|
|
559
|
+
// Create the intermediate representation of each style; this only needs to happen once
|
|
560
|
+
// The intermediate transition style holds the transition numerical values and the unit of measurement separately
|
|
561
|
+
if (!this._intermediateTransitionStyle) {
|
|
562
|
+
this._intermediateTransitionStyle = {};
|
|
563
|
+
|
|
564
|
+
for (var key in sourceStyle) {
|
|
565
|
+
// Extract the numeric values
|
|
566
|
+
this._intermediateTransitionStyle[key] = {
|
|
567
|
+
source: parseFloat(sourceStyle[key])
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
var target = parseFloat(targetStyle[key]);
|
|
571
|
+
if (isNaN(target)) target = parseFloat(BMCollectionViewLayoutAttributesStyleDefaults[key]);
|
|
572
|
+
this._intermediateTransitionStyle[key].target = target;
|
|
573
|
+
|
|
574
|
+
// Extract the unit from the source style
|
|
575
|
+
// At this point, having different units for the same property in the source and target styles is unsupported
|
|
576
|
+
var unit = _BMCollectionViewTransitionLayoutAttributesUnitRegex.exec(sourceStyle[key])[1] || '';
|
|
577
|
+
this._intermediateTransitionStyle[key].unit = unit;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Get the remaining attributes from the target style
|
|
581
|
+
for (var key in targetStyle) {
|
|
582
|
+
// Skip previously added style attributes
|
|
583
|
+
if (this._intermediateTransitionStyle[key]) continue;
|
|
584
|
+
|
|
585
|
+
// Extract the numeric values
|
|
586
|
+
this._intermediateTransitionStyle[key] = {
|
|
587
|
+
target: parseFloat(targetStyle[key])
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
var source = parseFloat(sourceStyle[key]);
|
|
591
|
+
if (isNaN(source)) source = parseFloat(BMCollectionViewLayoutAttributesStyleDefaults[key]);
|
|
592
|
+
this._intermediateTransitionStyle[key].source = source;
|
|
593
|
+
|
|
594
|
+
// Extract the unit from the source style
|
|
595
|
+
// At this point, having different units for the same property in the source and target styles is unsupported
|
|
596
|
+
var unit = _BMCollectionViewTransitionCellAttributesUnitRegex.exec(targetStyle[key])[1] || '';
|
|
597
|
+
this._intermediateTransitionStyle[key].unit = unit;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
var transitionStyle = this._intermediateTransitionStyle;
|
|
603
|
+
|
|
604
|
+
// Compute the interpolated style
|
|
605
|
+
for (var key in transitionStyle) {
|
|
606
|
+
var style = transitionStyle[key];
|
|
607
|
+
this._style[key] = BMNumberByInterpolatingNumbersWithFraction(style.source, style.target, fraction) + style.unit;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// Apply the interpolated style
|
|
611
|
+
this.hook(this._style);
|
|
612
|
+
},
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Invoked by transition layouts at the end of a layout transition.
|
|
617
|
+
* Causes the transition attributes to apply the final target attributes to its associated cells.
|
|
618
|
+
*/
|
|
619
|
+
_applyFinalAttributes: function () {
|
|
620
|
+
if (this._cell) {
|
|
621
|
+
this._cell.attributes = this._targetAttributes;
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Invoked by transition layouts at the beginning of a layout transition.
|
|
628
|
+
* Causes the transition attributes to trigger an animated layout pass on its associated cell.
|
|
629
|
+
*/
|
|
630
|
+
_layout() {
|
|
631
|
+
if (this._cell) {
|
|
632
|
+
this._frame = this._targetAttributes.frame;
|
|
633
|
+
this._cell.needsLayout = YES;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Constructs and returns a new set of transition attributes object that will transition from the given source attributes to
|
|
641
|
+
* the given target attributes.
|
|
642
|
+
* @param sourceAttributes <BMCollectionViewLayoutAttributes> The source attributes.
|
|
643
|
+
* {
|
|
644
|
+
* @param targetAttributes <BMCollectionViewLayoutAttributes> The target attributes.
|
|
645
|
+
* }
|
|
646
|
+
* @return <_BMCollectionViewTransitionLayoutAttributes> The new transition attributes.
|
|
647
|
+
*/
|
|
648
|
+
export function _BMCollectionViewTransitionLayoutAttributesMakeWithSourceAttributes(sourceAttributes, options) {
|
|
649
|
+
var attributes = new _BMCollectionViewTransitionLayoutAttributes();
|
|
650
|
+
|
|
651
|
+
attributes.indexPath = sourceAttributes.indexPath.copy();
|
|
652
|
+
attributes._itemType = sourceAttributes._itemType;
|
|
653
|
+
attributes.identifier = sourceAttributes.identifier;
|
|
654
|
+
|
|
655
|
+
attributes._sourceAttributes = sourceAttributes;
|
|
656
|
+
attributes._targetAttributes = options.targetAttributes;
|
|
657
|
+
|
|
658
|
+
attributes.fraction = 0;
|
|
659
|
+
attributes._frame = sourceAttributes._frame;
|
|
660
|
+
|
|
661
|
+
return attributes;
|
|
662
|
+
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* @deprecated Deprecated. Use <code>_BMCollectionViewTransitionLayoutAttributesMakeWithSourceAttributes</code> instead.
|
|
667
|
+
*/
|
|
668
|
+
var _BMCollectionViewTransitionCellAttributesMakeWithSourceAttributes = _BMCollectionViewTransitionLayoutAttributesMakeWithSourceAttributes;
|
|
669
|
+
|
|
670
|
+
// @endtype
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
|