void _insertChild(int index, MergeableMaterialItem child) { this._children.Insert(index, child); if (child is MaterialGap) { this._initGap((MaterialGap)child); } }
void _removeChild(int index) { MergeableMaterialItem child = this._children[index]; this._children.RemoveAt(index); if (child is MaterialGap) { this._animationTuples[child.key] = null; } }
public override void initState() { base.initState(); _children = new List <MergeableMaterialItem>(); _children.AddRange(widget.children); for (int i = 0; i < _children.Count; i++) { MergeableMaterialItem child = _children[i]; if (child is MaterialGap) { _initGap((MaterialGap)_children[i]); _animationTuples[child.key].controller.setValue(1.0f); } } D.assert(_debugGapsAreValid(_children)); }
public override void didUpdateWidget(StatefulWidget oldWidget) { base.didUpdateWidget(oldWidget); MergeableMaterial _oldWidget = (MergeableMaterial)oldWidget; HashSet <LocalKey> oldKeys = new HashSet <LocalKey>(); foreach (MergeableMaterialItem child in _oldWidget.children) { oldKeys.Add(child.key); } HashSet <LocalKey> newKeys = new HashSet <LocalKey>(); foreach (MergeableMaterialItem child in widget.children) { newKeys.Add(child.key); } HashSet <LocalKey> newOnly = new HashSet <LocalKey>(); foreach (var key in newKeys) { if (!oldKeys.Contains(key)) { newOnly.Add(key); } } HashSet <LocalKey> oldOnly = new HashSet <LocalKey>(); foreach (var key in oldKeys) { if (!newKeys.Contains(key)) { oldOnly.Add(key); } } List <MergeableMaterialItem> newChildren = widget.children; int i = 0; int j = 0; D.assert(_debugGapsAreValid(newChildren)); _removeEmptyGaps(); while (i < newChildren.Count && j < _children.Count) { if (newOnly.Contains(newChildren[i].key) || oldOnly.Contains(_children[j].key)) { int startNew = i; int startOld = j; while (newOnly.Contains(newChildren[i].key)) { i++; } while (oldOnly.Contains(_children[j].key) || _isClosingGap(j)) { j++; } int newLength = i - startNew; int oldLength = j - startOld; if (newLength > 0) { if (oldLength > 1 || oldLength == 1 && _children[startOld] is MaterialSlice) { if (newLength == 1 && newChildren[startNew] is MaterialGap) { float gapSizeSum = 0.0f; while (startOld < j) { MergeableMaterialItem child = _children[startOld]; if (child is MaterialGap materialGap) { MaterialGap gap = materialGap; gapSizeSum += gap.size; } _removeChild(startOld); j--; } _insertChild(startOld, newChildren[startNew]); _animationTuples[newChildren[startNew].key].gapStart = gapSizeSum; _animationTuples[newChildren[startNew].key].controller.forward(); j++; } else { for (int k = 0; k < oldLength; k++) { _removeChild(startOld); } for (int k = 0; k < newLength; k++) { _insertChild(startOld + k, newChildren[startNew + k]); } j += (newLength - oldLength); } } else if (oldLength == 1) { if (newLength == 1 && newChildren[startNew] is MaterialGap && _children[startOld].key == newChildren[startNew].key) { _animationTuples[newChildren[startNew].key].controller.forward(); } else { float gapSize = _getGapSize(startOld); _removeChild(startOld); for (int k = 0; k < newLength; k++) { _insertChild(startOld + k, newChildren[startNew + k]); } j += (newLength - 1); float gapSizeSum = 0.0f; for (int k = startNew; k < i; k++) { MergeableMaterialItem newChild = newChildren[k]; if (newChild is MaterialGap materialGap) { gapSizeSum += materialGap.size; } } for (int k = startNew; k < i; k++) { MergeableMaterialItem newChild = newChildren[k]; if (newChild is MaterialGap materialGap) { _animationTuples[materialGap.key].gapStart = gapSize * materialGap.size / gapSizeSum; _animationTuples[materialGap.key].controller.setValue(0.0f); _animationTuples[materialGap.key].controller.forward(); } } } } else { for (int k = 0; k < newLength; k++) { MergeableMaterialItem newChild = newChildren[startNew + k]; _insertChild(startOld + k, newChild); if (newChild is MaterialGap gap) { _animationTuples[gap.key].controller.forward(); } } j += newLength; } } else { if (oldLength > 1 || oldLength == 1 && _children[startOld] is MaterialSlice) { float gapSizeSum = 0.0f; while (startOld < j) { MergeableMaterialItem child = _children[startOld]; if (child is MaterialGap materialGap) { gapSizeSum += materialGap.size; } _removeChild(startOld); j--; } if (gapSizeSum != 0.0) { MaterialGap gap = new MaterialGap(key: new UniqueKey(), size: gapSizeSum); _insertChild(startOld, gap); _animationTuples[gap.key].gapStart = 0.0f; _animationTuples[gap.key].controller.setValue(1.0f); _animationTuples[gap.key].controller.reverse(); j++; } } else if (oldLength == 1) { MaterialGap gap = (MaterialGap)_children[startOld]; _animationTuples[gap.key].gapStart = 0.0f; _animationTuples[gap.key].controller.reverse(); } } } else { if ((_children[j] is MaterialGap) == (newChildren[i] is MaterialGap)) { _children[j] = newChildren[i]; i++; j++; } else { D.assert(_children[j] is MaterialGap); j++; } } } while (j < _children.Count) { _removeChild(j); } while (i < newChildren.Count) { _insertChild(j, newChildren[i]); i++; j++; } }