|
|
|
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using Unity.UIWidgets.animation; |
|
|
|
using Unity.UIWidgets.foundation; |
|
|
|
using Unity.UIWidgets.gestures; |
|
|
|
|
|
|
float stretchTriggerOffset = 100.0f, |
|
|
|
AsyncCallback onStretchTrigger = null |
|
|
|
) { |
|
|
|
D.assert(stretchTriggerOffset != null); |
|
|
|
this.stretchTriggerOffset = stretchTriggerOffset; |
|
|
|
this.onStretchTrigger = onStretchTrigger; |
|
|
|
} |
|
|
|
|
|
|
this.stretchConfiguration = stretchConfiguration; |
|
|
|
} |
|
|
|
|
|
|
|
float _lastStretchOffset; |
|
|
|
public virtual float? maxExtent { get; } |
|
|
|
|
|
|
|
public virtual float? minExtent { get; } |
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
throw new UIWidgetsError( |
|
|
|
"The maxExtent for this $runtimeType is less than its minExtent.\n" + |
|
|
|
"The specified maxExtent was: ${maxExtent.toStringAsFixed(1)}\n" + |
|
|
|
"The specified minExtent was: ${minExtent.toStringAsFixed(1)}\n" |
|
|
|
); |
|
|
|
throw new UIWidgetsError(new List<DiagnosticsNode>{ |
|
|
|
new ErrorSummary($"The maxExtent for this {GetType()} is less than its minExtent."), |
|
|
|
new FloatProperty("The specified maxExtent was", maxExtent), |
|
|
|
new FloatProperty("The specified minExtent was", minExtent), |
|
|
|
}); |
|
|
|
float stretchOffset = 0.0f; |
|
|
|
if (stretchConfiguration != null && childMainAxisPosition(child) == 0.0) |
|
|
|
stretchOffset += constraints.overlap.abs(); |
|
|
|
this.constraints.asBoxConstraints( |
|
|
|
maxExtent: Mathf.Max(minExtent ?? 0.0f, maxExtent - shrinkOffset)), |
|
|
|
constraints.asBoxConstraints( |
|
|
|
maxExtent: Mathf.Max(minExtent?? 0.0f, maxExtent - shrinkOffset) + stretchOffset |
|
|
|
), |
|
|
|
if (stretchConfiguration != null && |
|
|
|
stretchConfiguration.onStretchTrigger != null && |
|
|
|
stretchOffset >= stretchConfiguration.stretchTriggerOffset && |
|
|
|
_lastStretchOffset <= stretchConfiguration.stretchTriggerOffset) { |
|
|
|
stretchConfiguration.onStretchTrigger(); |
|
|
|
} |
|
|
|
_lastStretchOffset = stretchOffset; |
|
|
|
} |
|
|
|
|
|
|
|
public override float? childMainAxisPosition(RenderObject child) { |
|
|
|
|
|
|
protected override bool hitTestChildren(SliverHitTestResult result, float mainAxisPosition, float crossAxisPosition) { |
|
|
|
protected override bool hitTestChildren(SliverHitTestResult result, float mainAxisPosition = 0.0f, float crossAxisPosition = 0.0f) { |
|
|
|
D.assert(geometry.hitTestExtent > 0.0f); |
|
|
|
if (child != null) { |
|
|
|
return RenderSliverHelpers.hitTestBoxChild(this, new BoxHitTestResult(result), child, mainAxisPosition: mainAxisPosition, |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected bool excludeFromSemanticsScrolling { |
|
|
|
get { return _excludeFromSemanticsScrolling; } |
|
|
|
set { |
|
|
|
if (_excludeFromSemanticsScrolling == value) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
_excludeFromSemanticsScrolling = value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool _excludeFromSemanticsScrolling = false; |
|
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
base.debugFillProperties(properties); |
|
|
|
properties.add(FloatProperty.lazy("maxExtent", () => maxExtent)); |
|
|
|
|
|
|
maxPaintExtent: maxExtent ?? 0.0f, |
|
|
|
hasVisualOverflow: true |
|
|
|
); |
|
|
|
_childPosition = Mathf.Min(0.0f, paintExtent ?? 0.0f - childExtent); |
|
|
|
_childPosition = updateGeometry(); |
|
|
|
} |
|
|
|
|
|
|
|
public override float? childMainAxisPosition(RenderObject child) { |
|
|
|
|
|
|
) : base(child: child, |
|
|
|
stretchConfiguration: stretchConfiguration) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SliverConstraints constraints = this.constraints; |
|
|
|
excludeFromSemanticsScrolling = |
|
|
|
overlapsContent || (constraints.scrollOffset > maxExtent - minExtent); |
|
|
|
float? layoutExtent = |
|
|
|
(maxExtent - constraints.scrollOffset)?.clamp(0.0f, constraints.remainingPaintExtent); |
|
|
|
float effectiveRemainingPaintExtent = Mathf.Max(0, constraints.remainingPaintExtent - constraints.overlap); |
|
|
|
float? layoutExtent = (maxExtent - constraints.scrollOffset)?.clamp(0.0f, effectiveRemainingPaintExtent); |
|
|
|
float stretchOffset = stretchConfiguration != null ? |
|
|
|
constraints.overlap.abs() : |
|
|
|
0.0f; |
|
|
|
paintExtent: Mathf.Min(childExtent, constraints.remainingPaintExtent), |
|
|
|
paintExtent: Mathf.Min(childExtent, effectiveRemainingPaintExtent), |
|
|
|
maxPaintExtent: maxExtent ?? 0.0f, |
|
|
|
maxPaintExtent: (maxExtent ?? 0.0f) + stretchOffset, |
|
|
|
maxScrollObstructionExtent: minExtent ?? 0.0f, |
|
|
|
cacheExtent: layoutExtent > 0.0f ? -constraints.cacheOrigin + layoutExtent : layoutExtent, |
|
|
|
hasVisualOverflow: true |
|
|
|
|
|
|
TimeSpan? duration = null |
|
|
|
) { |
|
|
|
D.assert(vsync != null); |
|
|
|
D.assert(curve != null); |
|
|
|
D.assert(duration != null); |
|
|
|
this.vsync = vsync; |
|
|
|
this.curve = curve ?? Curves.ease; |
|
|
|
this.duration = duration ?? new TimeSpan(0, 0, 0, 0, 300); |
|
|
|
|
|
|
FloatingHeaderSnapConfiguration _snapConfiguration; |
|
|
|
|
|
|
|
protected virtual float updateGeometry() { |
|
|
|
float stretchOffset = 0.0f; |
|
|
|
if (stretchConfiguration != null && _childPosition == 0.0) { |
|
|
|
stretchOffset += constraints.overlap.abs(); |
|
|
|
} |
|
|
|
float? maxExtent = this.maxExtent; |
|
|
|
float? paintExtent = maxExtent - _effectiveScrollOffset; |
|
|
|
float? layoutExtent = maxExtent - constraints.scrollOffset; |
|
|
|
|
|
|
paintExtent: paintExtent?.clamp(0.0f, constraints.remainingPaintExtent) ?? 0.0f, |
|
|
|
layoutExtent: layoutExtent?.clamp(0.0f, constraints.remainingPaintExtent), |
|
|
|
maxPaintExtent: maxExtent ?? 0.0f, |
|
|
|
maxScrollObstructionExtent: maxExtent ?? 0.0f, |
|
|
|
maxPaintExtent: (maxExtent ?? 0.0f) + stretchOffset, |
|
|
|
return Mathf.Min(0.0f, paintExtent ?? 0.0f - childExtent); |
|
|
|
return stretchOffset > 0 ? 0.0f : Mathf.Min(0.0f, paintExtent??0.0f - childExtent); |
|
|
|
} |
|
|
|
|
|
|
|
public void maybeStartSnapAnimation(ScrollDirection direction) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
protected override void performLayout() { |
|
|
|
SliverConstraints constraints = this.constraints; |
|
|
|
float? maxExtent = this.maxExtent; |
|
|
|
if (((constraints.scrollOffset < _lastActualScrollOffset) || |
|
|
|
(_effectiveScrollOffset < maxExtent))) { |
|
|
|
|
|
|
else { |
|
|
|
_effectiveScrollOffset = constraints.scrollOffset; |
|
|
|
} |
|
|
|
|
|
|
|
excludeFromSemanticsScrolling = overlapsContent; |
|
|
|
layoutChild(_effectiveScrollOffset, maxExtent ?? 0.0f, overlapsContent: overlapsContent); |
|
|
|
layoutChild( |
|
|
|
_effectiveScrollOffset, |
|
|
|
maxExtent ?? 0.0f, |
|
|
|
overlapsContent: overlapsContent |
|
|
|
); |
|
|
|
_childPosition = updateGeometry(); |
|
|
|
_lastActualScrollOffset = constraints.scrollOffset; |
|
|
|
} |
|
|
|
|
|
|
scrollExtent: maxExtent ?? 0.0f, |
|
|
|
paintExtent: clampedPaintExtent ?? 0.0f, |
|
|
|
layoutExtent: layoutExtent?.clamp(0.0f, clampedPaintExtent ?? 0.0f), |
|
|
|
maxPaintExtent: maxExtent + stretchOffset ?? 0.0f, |
|
|
|
maxPaintExtent: (maxExtent ?? 0.0f) + (stretchOffset ?? 0.0f), |
|
|
|
maxScrollObstructionExtent: maxExtent ?? 0.0f, |
|
|
|
hasVisualOverflow: true |
|
|
|
); |
|
|
|