|
|
|
|
|
|
using System.Collections.Generic; |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using Unity.UIWidgets.async2; |
|
|
|
using Unity.UIWidgets.widgets; |
|
|
|
using UnityEngine; |
|
|
|
using Canvas = Unity.UIWidgets.ui.Canvas; |
|
|
|
using Color = Unity.UIWidgets.ui.Color; |
|
|
|
|
|
|
public class AnnotationResult<T> { |
|
|
|
public readonly List<AnnotationEntry<T>> _entries = new List<AnnotationEntry<T>>(); |
|
|
|
|
|
|
|
void add(AnnotationEntry<T> entry) { |
|
|
|
public void add(AnnotationEntry<T> entry) { |
|
|
|
} |
|
|
|
IEnumerable<AnnotationEntry<T>> entries { |
|
|
|
} |
|
|
|
|
|
|
|
public IEnumerable<AnnotationEntry<T>> entries { |
|
|
|
get { |
|
|
|
return _entries; |
|
|
|
} |
|
|
|
|
|
|
public bool _needsAddToScene = true; |
|
|
|
|
|
|
|
protected void markNeedsAddToScene() { |
|
|
|
D.assert( |
|
|
|
!alwaysNeedsAddToScene,()=> |
|
|
|
GetType().ToString() +" with alwaysNeedsAddToScene set called markNeedsAddToScene.\n" + |
|
|
|
"The layer's alwaysNeedsAddToScene is set to true, and therefore it should not call markNeedsAddToScene." |
|
|
|
); |
|
|
|
if (_needsAddToScene) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
void debugMarkClean() { |
|
|
|
D.assert(()=> { |
|
|
|
_needsAddToScene = false; |
|
|
|
return true; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
bool debugSubtreeNeedsAddToScene { |
|
|
|
get { |
|
|
|
bool result; |
|
|
|
D.assert(()=>{ |
|
|
|
result = _needsAddToScene; |
|
|
|
return true; |
|
|
|
}); |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal bool _subtreeNeedsAddToScene; |
|
|
|
|
|
|
|
|
|
|
public Layer nextSibling { |
|
|
|
get { return _nextSibling; } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal Layer _previousSibling; |
|
|
|
|
|
|
|
protected override void dropChild(AbstractNodeMixinDiagnosticableTree child) { |
|
|
|
|
|
|
|
|
|
|
base.dropChild(child); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
base.adoptChild(child); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public virtual bool findAnnotations<S>( |
|
|
|
AnnotationResult<S> result, |
|
|
|
Offset localPosition, |
|
|
|
bool onlyFirst |
|
|
|
) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
S find<S>(Offset localPosition) { |
|
|
|
AnnotationResult<S> result = new AnnotationResult<S>(); |
|
|
|
findAnnotations<S>(result, localPosition, onlyFirst: true); |
|
|
|
return result.entries.Count() == 0 ? default : result.entries.First().annotation; |
|
|
|
} |
|
|
|
/* |
|
|
|
@Deprecated( |
|
|
|
'Use findAllAnnotations(...).annotations instead. ' |
|
|
|
'This feature was deprecated after v1.10.14.' |
|
|
|
) |
|
|
|
Iterable<S> findAll<S>(Offset localPosition) { |
|
|
|
final AnnotationResult<S> result = findAllAnnotations(localPosition); |
|
|
|
return result.entries.map((AnnotationEntry<S> entry) => entry.annotation); |
|
|
|
}*/ |
|
|
|
AnnotationResult<S> findAllAnnotations<S>(Offset localPosition) { |
|
|
|
AnnotationResult<S> result = new AnnotationResult<S>(); |
|
|
|
findAnnotations<S>(result, localPosition, onlyFirst: false); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
public abstract void addToScene(SceneBuilder builder, Offset layerOffset = null); |
|
|
|
|
|
|
|
internal void _addToSceneWithRetainedRendering(SceneBuilder builder) { |
|
|
|
if (!_needsAddToScene && _engineLayer != null) { |
|
|
|
builder.addRetained(_engineLayer); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
addToScene(builder); |
|
|
|
_needsAddToScene = false; |
|
|
|
} |
|
|
|
public object debugCreator; |
|
|
|
|
|
|
|
public override string toStringShort() { |
|
|
|
return base.toStringShort() + (owner == null ? " DETACHED" : ""); |
|
|
|
} |
|
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
base.debugFillProperties(properties); |
|
|
|
properties.add(new DiagnosticsProperty<object>("owner", owner, |
|
|
|
level: parent != null ? DiagnosticLevel.hidden : DiagnosticLevel.info, |
|
|
|
defaultValue: foundation_.kNullDefaultValue)); |
|
|
|
properties.add(new DiagnosticsProperty<object>("creator", debugCreator, |
|
|
|
defaultValue: foundation_.kNullDefaultValue, level: DiagnosticLevel.debug)); |
|
|
|
} |
|
|
|
public void replaceWith(Layer newLayer) { |
|
|
|
D.assert(parent != null); |
|
|
|
D.assert(attached == parent.attached); |
|
|
|
|
|
|
D.assert(!attached); |
|
|
|
} |
|
|
|
|
|
|
|
internal abstract S find<S>(Offset regionOffset) where S : class; |
|
|
|
|
|
|
|
internal abstract void addToScene(SceneBuilder builder, Offset layerOffset = null); |
|
|
|
//internal abstract S find<S>(Offset regionOffset) where S : class;
|
|
|
|
internal void _addToSceneWithRetainedRendering(SceneBuilder builder) { |
|
|
|
if (!_needsAddToScene && _engineLayer != null) { |
|
|
|
builder.addRetained(_engineLayer); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
addToScene(builder); |
|
|
|
_needsAddToScene = false; |
|
|
|
} |
|
|
|
|
|
|
|
public object debugCreator; |
|
|
|
|
|
|
|
public override string toStringShort() { |
|
|
|
return base.toStringShort() + (owner == null ? " DETACHED" : ""); |
|
|
|
} |
|
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
base.debugFillProperties(properties); |
|
|
|
properties.add(new DiagnosticsProperty<object>("owner", owner, |
|
|
|
level: parent != null ? DiagnosticLevel.hidden : DiagnosticLevel.info, |
|
|
|
defaultValue: foundation_.kNullDefaultValue)); |
|
|
|
properties.add(new DiagnosticsProperty<object>("creator", debugCreator, |
|
|
|
defaultValue: foundation_.kNullDefaultValue, level: DiagnosticLevel.debug)); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public class PictureLayer : Layer { |
|
|
|
|
|
|
public readonly Rect canvasBounds; |
|
|
|
|
|
|
|
Picture _picture; |
|
|
|
|
|
|
|
public Picture picture { |
|
|
|
get { return _picture; } |
|
|
|
set { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
bool _isComplexHint = false; |
|
|
|
|
|
|
|
bool _isComplexHint = false; |
|
|
|
public bool isComplexHint { |
|
|
|
get { return _isComplexHint; } |
|
|
|
set { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
bool _willChangeHint = false; |
|
|
|
|
|
|
|
public bool willChangeHint { |
|
|
|
get { return _willChangeHint; } |
|
|
|
set { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
/*internal override S find<S>(Offset regionOffset) { |
|
|
|
} |
|
|
|
}*/ |
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
|
|
|
|
builder.addPicture(layerOffset, picture, |
|
|
|
isComplexHint: isComplexHint, willChangeHint: willChangeHint); |
|
|
|
} |
|
|
|
|
|
|
properties.add(new DiagnosticsProperty<Rect>("paint bounds", canvasBounds)); |
|
|
|
properties.add(new DiagnosticsProperty<string>("picture", _picture.GetType().ToString)); |
|
|
|
properties.add(new DiagnosticsProperty<string>( |
|
|
|
"raster cache hints", |
|
|
|
"isComplex =" + isComplexHint + "willChange ="+ willChangeHint) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition,bool onlyFirst ) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
bool freeze = false |
|
|
|
) { |
|
|
|
D.assert(rect != null); |
|
|
|
|
|
|
|
D.assert(textureId != null); |
|
|
|
this.rect = rect; |
|
|
|
this.textureId = textureId; |
|
|
|
this.freeze = freeze; |
|
|
|
|
|
|
|
|
|
|
public readonly bool freeze; |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
return null; |
|
|
|
|
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
return false; |
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
layerOffset = layerOffset ?? Offset.zero; |
|
|
|
|
|
|
|
Rect shiftedRect = rect.shift(layerOffset); |
|
|
|
|
|
|
public Layer firstChild { |
|
|
|
get { return _firstChild; } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
Layer current = lastChild; |
|
|
|
while (current != null) { |
|
|
|
S value = current.find<S>(regionOffset); |
|
|
|
if (value != null) { |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
current = current.previousSibling; |
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
internal bool findAnnotations<S>( |
|
|
|
AnnotationResult<S> result, |
|
|
|
Offset localPosition, |
|
|
|
bool onlyFirst = false |
|
|
|
) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
public AnnotationResult<S> findAllAnnotations<S>(Offset localPosition) { |
|
|
|
AnnotationResult<S> result = new AnnotationResult<S>(); |
|
|
|
findAnnotations<S>(result, localPosition, onlyFirst: false); |
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
internal Layer _lastChild; |
|
|
|
|
|
|
|
public ui.Scene buildScene(ui.SceneBuilder builder) { |
|
|
|
List<PictureLayer> temporaryLayers = new List<PictureLayer>(); |
|
|
|
D.assert(()=> { |
|
|
|
|
|
|
}); |
|
|
|
return scene; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal Layer _lastChild; |
|
|
|
|
|
|
|
bool _debugUltimatePreviousSiblingOf(Layer child, Layer equals = null) { |
|
|
|
D.assert(child.attached == attached); |
|
|
|
while (child.previousSibling != null) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return child == equals; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
child = child._nextSibling; |
|
|
|
D.assert(child.attached == attached); |
|
|
|
} |
|
|
|
|
|
|
|
return child == equals; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
child = child.nextSibling; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*internal override S find<S>(Offset regionOffset) { |
|
|
|
Layer current = lastChild; |
|
|
|
while (current != null) { |
|
|
|
S value = current.find<S>(regionOffset); |
|
|
|
if (value != null) { |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
current = current.previousSibling; |
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
}*/ |
|
|
|
public override bool findAnnotations<S>( |
|
|
|
AnnotationResult<S> result, |
|
|
|
Offset localPosition, |
|
|
|
bool onlyFirst |
|
|
|
) { |
|
|
|
for (Layer child = lastChild; child != null; child = child.previousSibling) { |
|
|
|
bool isAbsorbed = child.findAnnotations<S>(result, localPosition, onlyFirst: onlyFirst); |
|
|
|
if (isAbsorbed) |
|
|
|
return true; |
|
|
|
if (onlyFirst && result.entries.Count() != 0) |
|
|
|
return isAbsorbed; |
|
|
|
} |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
public AnnotationResult<S> findAllAnnotations<S>(Offset localPosition) { |
|
|
|
AnnotationResult<S> result = new AnnotationResult<S>(); |
|
|
|
findAnnotations<S>(result, localPosition, onlyFirst: false); |
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void attach(object owner) { |
|
|
|
base.attach(owner); |
|
|
|
|
|
|
while (node.parent != null) { |
|
|
|
node = node.parent; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
D.assert(child.attached == attached); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
_lastChild = null; |
|
|
|
} |
|
|
|
|
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
addChildrenToScene(builder, layerOffset); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
else { |
|
|
|
child.addToScene(builder, childOffset); |
|
|
|
} |
|
|
|
|
|
|
|
child = child.nextSibling; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
if (firstChild == null) { |
|
|
|
return new List<Layer>(); |
|
|
|
} |
|
|
|
|
|
|
|
List<Layer> children = new List<Layer>(); |
|
|
|
Layer child = firstChild; |
|
|
|
while (child != null) { |
|
|
|
|
|
|
if (firstChild == null) { |
|
|
|
return children; |
|
|
|
} |
|
|
|
|
|
|
|
Layer child = firstChild; |
|
|
|
int count = 1; |
|
|
|
while (true) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
count += 1; |
|
|
|
child = child.nextSibling; |
|
|
|
} |
|
|
|
|
|
|
public OffsetLayer(Offset offset = null) { |
|
|
|
_offset = offset ?? Offset.zero; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Offset offset { |
|
|
|
get { return _offset; } |
|
|
|
set { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
return base.find<S>(regionOffset - offset); |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst) { |
|
|
|
return base.findAnnotations<S>(result, localPosition - offset, onlyFirst: onlyFirst); |
|
|
|
transform.translate(offset.dx, offset.dy); |
|
|
|
transform.multiply(Matrix4.translationValues(offset.dx, offset.dy, 0.0f)); |
|
|
|
} |
|
|
|
|
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
layerOffset = layerOffset ?? Offset.zero; |
|
|
|
|
|
|
|
engineLayer = builder.pushOffset( |
|
|
|
(float) (layerOffset.dx + offset.dx), |
|
|
|
(float) (layerOffset.dy + offset.dy), |
|
|
|
oldLayer: engineLayer as OffsetEngineLayer); |
|
|
|
addChildrenToScene(builder); |
|
|
|
builder.pop(); |
|
|
|
} |
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
base.debugFillProperties(properties); |
|
|
|
properties.add(new DiagnosticsProperty<Offset>("offset", offset)); |
|
|
|
} |
|
|
|
|
|
|
|
public Scene buildScene(SceneBuilder builder) { |
|
|
|
|
|
|
}); |
|
|
|
return scene; |
|
|
|
} |
|
|
|
|
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
layerOffset = layerOffset ?? Offset.zero; |
|
|
|
Future<ui.Image> toImage(Rect bounds, float pixelRatio = 1.0f)// async
|
|
|
|
{ |
|
|
|
D.assert(bounds != null); |
|
|
|
D.assert(pixelRatio != null); |
|
|
|
ui.SceneBuilder builder = new SceneBuilder(); |
|
|
|
Matrix4 transform = Matrix4.translationValues( |
|
|
|
(-bounds.left - offset.dx) * pixelRatio, |
|
|
|
(-bounds.top - offset.dy) * pixelRatio, |
|
|
|
0.0f |
|
|
|
); |
|
|
|
transform.scale(pixelRatio, pixelRatio); |
|
|
|
builder.pushTransform(transform.storage); |
|
|
|
ui.Scene scene = buildScene(builder); |
|
|
|
engineLayer = builder.pushOffset( |
|
|
|
(float) (layerOffset.dx + offset.dx), |
|
|
|
(float) (layerOffset.dy + offset.dy), |
|
|
|
oldLayer: engineLayer as OffsetEngineLayer); |
|
|
|
addChildrenToScene(builder); |
|
|
|
builder.pop(); |
|
|
|
try { |
|
|
|
// Size is rounded up to the next pixel to make sure we don't clip off
|
|
|
|
// anything.
|
|
|
|
return scene.toImage( |
|
|
|
(pixelRatio * bounds.width).ceil(), |
|
|
|
(pixelRatio * bounds.height).ceil() |
|
|
|
); |
|
|
|
} finally { |
|
|
|
scene.Dispose(); |
|
|
|
} |
|
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
base.debugFillProperties(properties); |
|
|
|
properties.add(new DiagnosticsProperty<Offset>("offset", offset)); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public class ClipRectLayer : ContainerLayer { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Rect _clipRect; |
|
|
|
|
|
|
|
public Rect clipRect { |
|
|
|
get { return _clipRect; } |
|
|
|
set { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Clip _clipBehavior; |
|
|
|
|
|
|
|
D.assert(value != null); |
|
|
|
D.assert(value != Clip.none); |
|
|
|
if (value != _clipBehavior) { |
|
|
|
_clipBehavior = value; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
if (!clipRect.contains(regionOffset)) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
return base.find<S>(regionOffset); |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
if (!clipRect.contains(localPosition)) |
|
|
|
return false; |
|
|
|
return base.findAnnotations<S>(result, localPosition, onlyFirst: onlyFirst); |
|
|
|
|
|
|
|
|
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
D.assert(clipRect != null); |
|
|
|
D.assert(clipBehavior != null); |
|
|
|
|
|
|
|
bool enabled = true; |
|
|
|
D.assert(() => { |
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
base.debugFillProperties(properties); |
|
|
|
properties.add(new DiagnosticsProperty<Rect>("clipRect", clipRect)); |
|
|
|
properties.add(new DiagnosticsProperty<Clip>("clipBehavior", clipBehavior)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
_clipBehavior = clipBehavior; |
|
|
|
} |
|
|
|
|
|
|
|
RRect _clipRRect; |
|
|
|
|
|
|
|
RRect _clipRRect; |
|
|
|
public RRect clipRRect { |
|
|
|
get { return _clipRRect; } |
|
|
|
set { |
|
|
|
|
|
|
public Clip clipBehavior { |
|
|
|
get { return _clipBehavior; } |
|
|
|
set { |
|
|
|
D.assert(value != null); |
|
|
|
D.assert(value != Clip.none); |
|
|
|
if (value != _clipBehavior) { |
|
|
|
_clipBehavior = value; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
if (!clipRRect.contains(regionOffset)) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
return base.find<S>(regionOffset); |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
if (!clipRRect.contains(localPosition)) |
|
|
|
return false; |
|
|
|
return base.findAnnotations<S>(result, localPosition, onlyFirst: onlyFirst); |
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
|
|
|
|
D.assert(clipRRect != null); |
|
|
|
D.assert(clipBehavior != null); |
|
|
|
bool enabled = true; |
|
|
|
D.assert(() => { |
|
|
|
enabled = !D.debugDisableClipLayers; |
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
base.debugFillProperties(properties); |
|
|
|
properties.add(new DiagnosticsProperty<RRect>("clipRRect", clipRRect)); |
|
|
|
properties.add(new DiagnosticsProperty<Clip>("clipBehavior", clipBehavior)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
public Clip clipBehavior { |
|
|
|
get { return _clipBehavior; } |
|
|
|
set { |
|
|
|
D.assert(value != null); |
|
|
|
D.assert(value != Clip.none); |
|
|
|
if (value != _clipBehavior) { |
|
|
|
_clipBehavior = value; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
if (!clipPath.contains(regionOffset)) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
return base.find<S>(regionOffset); |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
if (!clipPath.contains(localPosition)) |
|
|
|
return false; |
|
|
|
return base.findAnnotations<S>(result, localPosition, onlyFirst: onlyFirst); |
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
D.assert(clipPath != null); |
|
|
|
D.assert(clipBehavior != null); |
|
|
|
|
|
|
|
bool enabled = true; |
|
|
|
D.assert(() => { |
|
|
|
|
|
|
builder.pop(); |
|
|
|
} |
|
|
|
} |
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
base.debugFillProperties(properties); |
|
|
|
properties.add(new DiagnosticsProperty<Clip>("clipBehavior", clipBehavior)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public class TransformLayer : OffsetLayer { |
|
|
|
|
|
|
|
|
|
|
public Matrix4 transform { |
|
|
|
get { return _transform; } |
|
|
|
} |
|
|
|
set { |
|
|
|
D.assert(value != null); |
|
|
|
//D.assert(value.storage.Each((float component) => ));
|
|
|
|
if (value == _transform) |
|
|
|
return; |
|
|
|
_transform = value; |
|
|
|
_inverseDirty = true; |
|
|
|
markNeedsAddToScene(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
if (_inverseDirty) { |
|
|
|
_invertedTransform = Matrix4.tryInvert( |
|
|
|
PointerEvent.removePerspectiveTransform(transform) |
|
|
|
); |
|
|
|
_inverseDirty = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (_invertedTransform == null) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
Vector4 vector = new Vector4(regionOffset.dx, regionOffset.dy, 0, 1); |
|
|
|
Vector4 result = _invertedTransform.transform(vector); |
|
|
|
return base.find<S>(new Offset(result[0], result[1])); |
|
|
|
} |
|
|
|
|
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
|
|
|
|
D.assert(transform != null); |
|
|
|
_lastEffectiveTransform = _transform; |
|
|
|
|
|
|
|
var totalOffset = offset + layerOffset; |
|
|
|
|
|
|
addChildrenToScene(builder); |
|
|
|
builder.pop(); |
|
|
|
} |
|
|
|
Offset _transformOffset(Offset localPosition) { |
|
|
|
if (_inverseDirty) { |
|
|
|
_invertedTransform = Matrix4.tryInvert( |
|
|
|
PointerEvent.removePerspectiveTransform(transform) |
|
|
|
); |
|
|
|
_inverseDirty = false; |
|
|
|
} |
|
|
|
if (_invertedTransform == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
return MatrixUtils.transformPoint(_invertedTransform, localPosition); |
|
|
|
} |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
Offset transformedOffset = _transformOffset(localPosition); |
|
|
|
if (transformedOffset == null) |
|
|
|
return false; |
|
|
|
return base.findAnnotations<S>(result, transformedOffset, onlyFirst: onlyFirst); |
|
|
|
} |
|
|
|
|
|
|
|
public override void applyTransform(Layer child, Matrix4 transform) { |
|
|
|
D.assert(child != null); |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
int _alpha; |
|
|
|
|
|
|
|
public int alpha { |
|
|
|
get { return _alpha; } |
|
|
|
set { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Offset _offset; |
|
|
|
|
|
|
|
public Offset offset { |
|
|
|
get { return _offset; } |
|
|
|
set { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
public override void applyTransform(Layer child, Matrix4 transform) { |
|
|
|
D.assert(child != null); |
|
|
|
D.assert(transform != null); |
|
|
|
transform.translate(offset.dx, offset.dy); |
|
|
|
} |
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
|
|
|
|
D.assert(alpha != null); |
|
|
|
bool enabled = firstChild != null; |
|
|
|
D.assert(() => { |
|
|
|
enabled = enabled && !D.debugDisableOpacityLayers; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ImageFilter _filter; |
|
|
|
|
|
|
|
public ImageFilter filter { |
|
|
|
get { return _filter; } |
|
|
|
set { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
D.assert(filter != null); |
|
|
|
engineLayer = builder.pushBackdropFilter( |
|
|
|
filter: filter, |
|
|
|
|
|
|
public LeaderLayer leader { |
|
|
|
get { return _leader; } |
|
|
|
} |
|
|
|
|
|
|
|
internal LeaderLayer _leader; |
|
|
|
|
|
|
|
public override string ToString() { |
|
|
|
|
|
|
public LeaderLayer(LayerLink link, Offset offset = null) { |
|
|
|
D.assert(link != null); |
|
|
|
offset = offset ?? Offset.zero; |
|
|
|
this.link = link; |
|
|
|
_link = link; |
|
|
|
public readonly LayerLink link; |
|
|
|
public LayerLink link { |
|
|
|
get { return _link; } |
|
|
|
set { |
|
|
|
D.assert(value != null); |
|
|
|
_link = value; |
|
|
|
} |
|
|
|
} |
|
|
|
LayerLink _link; |
|
|
|
public Offset offset; |
|
|
|
|
|
|
|
protected override bool alwaysNeedsAddToScene { |
|
|
|
|
|
|
|
|
|
|
internal Offset _lastOffset; |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
return base.find<S>(regionOffset - offset); |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
return base.findAnnotations<S>(result, localPosition - offset, onlyFirst: onlyFirst); |
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
|
|
|
|
|
|
|
|
D.assert(offset != null); |
|
|
|
_lastOffset = offset + layerOffset; |
|
|
|
if (_lastOffset != Offset.zero) { |
|
|
|
|
|
|
Offset linkedOffset = null |
|
|
|
) { |
|
|
|
D.assert(link != null); |
|
|
|
this.link = link; |
|
|
|
_link = link; |
|
|
|
public readonly LayerLink link; |
|
|
|
public LayerLink link { |
|
|
|
get { return _link; } |
|
|
|
set { |
|
|
|
D.assert(value != null); |
|
|
|
_link = value; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
LayerLink _link; |
|
|
|
|
|
|
|
public bool showWhenUnlinked; |
|
|
|
public Offset unlinkedOffset; |
|
|
|
public Offset linkedOffset; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
if (link.leader == null) { |
|
|
|
return showWhenUnlinked ? base.find<S>(regionOffset - unlinkedOffset) : null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Offset _transformOffset<S>(Offset localPosition) { |
|
|
|
|
|
|
|
if (_invertedTransform == null) { |
|
|
|
if (_invertedTransform == null) |
|
|
|
} |
|
|
|
|
|
|
|
Vector4 vector = new Vector4(regionOffset.dx, regionOffset.dy, 0, 1); |
|
|
|
Vector4 vector = new Vector4(localPosition.dx, localPosition.dy, 0.0f, 1.0f); |
|
|
|
return base.find<S>(new Offset(result[0] - linkedOffset.dx, result[1] - linkedOffset.dy)); |
|
|
|
return new Offset(result[0] - linkedOffset.dx, result[1] - linkedOffset.dy); |
|
|
|
} |
|
|
|
|
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
if (link.leader == null) { |
|
|
|
if (showWhenUnlinked) { |
|
|
|
return base.findAnnotations(result, localPosition - unlinkedOffset, onlyFirst: onlyFirst); |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
Offset transformedOffset = _transformOffset<S>(localPosition); |
|
|
|
if (transformedOffset == null) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
return base.findAnnotations<S>(result, transformedOffset, onlyFirst: onlyFirst); |
|
|
|
} |
|
|
|
|
|
|
|
public Matrix4 getLastTransform() { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
|
|
|
|
D.assert(link != null); |
|
|
|
D.assert(showWhenUnlinked != null); |
|
|
|
D.assert(link != null); |
|
|
|
if (link.leader == null && !showWhenUnlinked) { |
|
|
|
_lastTransform = null; |
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_establishTransform(); |
|
|
|
|
|
|
public class PerformanceOverlayLayer : Layer { |
|
|
|
public PerformanceOverlayLayer( |
|
|
|
Rect overlayRect = null, |
|
|
|
int? optionsMask = null |
|
|
|
int? optionsMask = null, |
|
|
|
int? rasterizerThreshold = null, |
|
|
|
bool? checkerboardRasterCacheImages = null, |
|
|
|
bool? checkerboardOffscreenLayers = null |
|
|
|
|
|
|
|
D.assert(overlayRect != null); |
|
|
|
D.assert(optionsMask != null); |
|
|
|
this.optionsMask = optionsMask ?? 0; |
|
|
|
this.optionsMask = optionsMask ; |
|
|
|
this.rasterizerThreshold = rasterizerThreshold ; |
|
|
|
this.checkerboardOffscreenLayers = checkerboardRasterCacheImages; |
|
|
|
this.checkerboardRasterCacheImages = checkerboardOffscreenLayers; |
|
|
|
} |
|
|
|
|
|
|
|
public Rect overlayRect { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public readonly int optionsMask; |
|
|
|
public readonly int? optionsMask; |
|
|
|
public readonly int? rasterizerThreshold; |
|
|
|
public readonly bool? checkerboardRasterCacheImages; |
|
|
|
public readonly bool? checkerboardOffscreenLayers; |
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
return null; |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
return false; |
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
builder.addPerformanceOverlay(optionsMask, shiftedOverlayRect); |
|
|
|
builder.addPerformanceOverlay((int)optionsMask, shiftedOverlayRect); |
|
|
|
//TODO: add implementations
|
|
|
|
//builder.setRasterizerTracingThreshold(rasterizerThreshold);
|
|
|
|
//builder.setCheckerboardRasterCacheImages(checkerboardRasterCacheImages);
|
|
|
|
|
|
|
public AnnotatedRegionLayer( |
|
|
|
T value = null, |
|
|
|
Size size = null, |
|
|
|
Offset offset = null) { |
|
|
|
Offset offset = null, |
|
|
|
bool opaque = false |
|
|
|
) { |
|
|
|
D.assert(opaque != null); |
|
|
|
this.opaque = opaque; |
|
|
|
} |
|
|
|
|
|
|
|
public readonly T value; |
|
|
|
|
|
|
public readonly Offset offset; |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
S result = base.find<S>(regionOffset); |
|
|
|
if (result != null) { |
|
|
|
return result; |
|
|
|
} |
|
|
|
public readonly bool opaque; |
|
|
|
if (size != null && !(offset & size).contains(regionOffset)) { |
|
|
|
return null; |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
bool isAbsorbed = base.findAnnotations(result, localPosition, onlyFirst: onlyFirst); |
|
|
|
if (result.entries.Count() != 0 && onlyFirst) |
|
|
|
return isAbsorbed; |
|
|
|
if (size != null && !(offset & size).contains(localPosition)) { |
|
|
|
return isAbsorbed; |
|
|
|
|
|
|
|
S typedResult = value as S; |
|
|
|
return typedResult; |
|
|
|
isAbsorbed = isAbsorbed || opaque; |
|
|
|
object untypedValue = value; |
|
|
|
S typedValue = (S)untypedValue; |
|
|
|
result.add(new AnnotationEntry<S>( |
|
|
|
annotation: typedValue, |
|
|
|
localPosition: localPosition - offset |
|
|
|
)); |
|
|
|
|
|
|
|
return base.find<S>(regionOffset); |
|
|
|
return isAbsorbed; |
|
|
|
} |
|
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
|
|
|
properties.add(new DiagnosticsProperty<Offset>("offset", offset, defaultValue: null)); |
|
|
|
properties.add(new DiagnosticsProperty<bool>("opaque", opaque, defaultValue: false)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.shadowColor = shadowColor; |
|
|
|
} |
|
|
|
|
|
|
|
public Path clipPath { |
|
|
|
public Path clipPath { |
|
|
|
get { return _clipPath; } |
|
|
|
set { |
|
|
|
if (value != _clipPath) { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Clip clipBehavior { |
|
|
|
get { return _clipBehavior; } |
|
|
|
set { |
|
|
|
if (value != _clipBehavior) { |
|
|
|
_clipBehavior = value; |
|
|
|
markNeedsAddToScene(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal Path _debugTransformedClipPath { |
|
|
|
get { |
|
|
|
ContainerLayer ancestor = parent; |
|
|
|
|
|
|
return clipPath.transform(matrix._m4storage); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Clip clipBehavior { |
|
|
|
get { return _clipBehavior; } |
|
|
|
set { |
|
|
|
if (value != _clipBehavior) { |
|
|
|
_clipBehavior = value; |
|
|
|
markNeedsAddToScene(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Clip _clipBehavior; |
|
|
|
|
|
|
|
public float elevation { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
float _elevation; |
|
|
|
|
|
|
|
public Color color { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Color _color; |
|
|
|
|
|
|
|
public Color shadowColor { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal override S find<S>(Offset regionOffset) { |
|
|
|
if (!clipPath.contains(regionOffset)) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
return base.find<S>(regionOffset); |
|
|
|
public override bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, bool onlyFirst ) { |
|
|
|
if (!clipPath.contains(localPosition)) |
|
|
|
return false; |
|
|
|
return base.findAnnotations<S>(result, localPosition, onlyFirst: onlyFirst); |
|
|
|
internal override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
public override void addToScene(SceneBuilder builder, Offset layerOffset = null) { |
|
|
|
D.assert(clipBehavior != null); |
|
|
|
D.assert(elevation != null); |
|
|
|
D.assert(color != null); |
|
|
|
D.assert(shadowColor != null); |
|
|
|
|
|
|
|
|
|
|
else { |
|
|
|
engineLayer = null; |
|
|
|
} |
|
|
|
|
|
|
|
addChildrenToScene(builder, layerOffset); |
|
|
|
if (enabled) { |
|
|
|
builder.pop(); |
|
|
|