您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

277 行
11 KiB

using System;
using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.painting {
public class ShapeDecoration : Decoration, IEquatable<ShapeDecoration> {
public ShapeDecoration(
Color color = null,
DecorationImage image = null,
Gradient gradient = null,
List<BoxShadow> shadows = null,
ShapeBorder shape = null
) {
D.assert(!(color != null && gradient != null));
D.assert(shape != null);
this.color = color;
this.image = image;
this.gradient = gradient;
this.shadows = shadows;
this.shape = shape;
}
public readonly Color color;
public readonly DecorationImage image;
public readonly Gradient gradient;
public readonly List<BoxShadow> shadows;
public readonly ShapeBorder shape;
public static ShapeDecoration fromBoxDecoration(BoxDecoration source) {
ShapeBorder shape = null;
switch (source.shape) {
case BoxShape.circle:
if (source.border != null) {
D.assert(source.border.isUniform);
shape = new CircleBorder(side: source.border.top);
} else {
shape = new CircleBorder();
}
break;
case BoxShape.rectangle:
if (source.borderRadius != null) {
D.assert(source.border == null || source.border.isUniform);
shape = new RoundedRectangleBorder(
side: source.border?.top ?? BorderSide.none,
borderRadius: source.borderRadius
);
} else {
shape = source.border ?? new Border();
}
break;
}
return new ShapeDecoration(
color: source.color,
image: source.image,
gradient: source.gradient,
shadows: source.boxShadow,
shape: shape
);
}
public override EdgeInsets padding {
get { return this.shape.dimensions; }
}
public override bool isComplex {
get { return this.shadows != null; }
}
public override Decoration lerpFrom(Decoration a, double t) {
if (a is BoxDecoration decoration) {
return ShapeDecoration.lerp(ShapeDecoration.fromBoxDecoration(decoration), this, t);
} else if (a == null || a is ShapeDecoration) {
return ShapeDecoration.lerp(a, this, t);
}
return base.lerpFrom(a, t);
}
public override Decoration lerpTo(Decoration b, double t) {
if (b is BoxDecoration decoration) {
return ShapeDecoration.lerp(this, ShapeDecoration.fromBoxDecoration(decoration), t);
} else if (b == null || b is ShapeDecoration) {
return ShapeDecoration.lerp(this, b, t);
}
return base.lerpTo(b, t);
}
public static ShapeDecoration lerp(ShapeDecoration a, ShapeDecoration b, double t) {
if (a == null && b == null) {
return null;
}
if (a != null && b != null) {
if (t == 0.0) {
return a;
}
if (t == 1.0) {
return b;
}
}
return new ShapeDecoration(
color: Color.lerp(a?.color, b?.color, t),
gradient: Gradient.lerp(a?.gradient, b?.gradient, t),
image: t < 0.5 ? a.image : b.image,
shadows: BoxShadow.lerpList(a?.shadows, b?.shadows, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t)
);
}
public bool Equals(ShapeDecoration other) {
if (ReferenceEquals(null, other)) {
return false;
}
if (ReferenceEquals(this, other)) {
return true;
}
return Equals(this.color, other.color) && Equals(this.image, other.image) &&
Equals(this.gradient, other.gradient) && Equals(this.shadows, other.shadows) &&
Equals(this.shape, other.shape);
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj)) {
return false;
}
if (ReferenceEquals(this, obj)) {
return true;
}
if (obj.GetType() != this.GetType()) {
return false;
}
return this.Equals((ShapeDecoration) obj);
}
public override int GetHashCode() {
unchecked {
var hashCode = (this.color != null ? this.color.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.image != null ? this.image.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.gradient != null ? this.gradient.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.shadows != null ? this.shadows.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.shape != null ? this.shape.GetHashCode() : 0);
return hashCode;
}
}
public static bool operator ==(ShapeDecoration left, ShapeDecoration right) {
return Equals(left, right);
}
public static bool operator !=(ShapeDecoration left, ShapeDecoration right) {
return !Equals(left, right);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.whitespace;
properties.add(new DiagnosticsProperty<Color>("color", this.color,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new DiagnosticsProperty<Gradient>("gradient", this.gradient,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new DiagnosticsProperty<DecorationImage>("image", this.image,
defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new EnumerableProperty<BoxShadow>("shadows", this.shadows,
defaultValue: Diagnostics.kNullDefaultValue, style: DiagnosticsTreeStyle.whitespace));
properties.add(new DiagnosticsProperty<ShapeBorder>("shape", this.shape));
}
public override bool hitTest(Size size, Offset position) {
return this.shape.getOuterPath(Offset.zero & size).contains(position);
}
public override BoxPainter createBoxPainter(VoidCallback onChanged = null) {
D.assert(onChanged != null || this.image == null);
return new _ShapeDecorationPainter(this, onChanged);
}
}
class _ShapeDecorationPainter : BoxPainter {
public _ShapeDecorationPainter(ShapeDecoration decoration, VoidCallback onChanged)
: base(onChanged) {
D.assert(decoration != null);
this._decoration = decoration;
}
readonly ShapeDecoration _decoration;
Rect _lastRect;
Path _outerPath;
Path _innerPath;
Paint _interiorPaint;
int? _shadowCount;
Path[] _shadowPaths;
Paint[] _shadowPaints;
void _precache(Rect rect) {
D.assert(rect != null);
if (rect == this._lastRect) {
return;
}
if (this._interiorPaint == null && (this._decoration.color != null || this._decoration.gradient != null)) {
this._interiorPaint = new Paint();
if (this._decoration.color != null) {
this._interiorPaint.color = this._decoration.color;
}
}
if (this._decoration.gradient != null) {
// this._interiorPaint.shader = this._decoration.gradient.createShader(rect);
}
if (this._decoration.shadows != null) {
if (this._shadowCount == null) {
this._shadowCount = this._decoration.shadows.Count;
this._shadowPaths = new Path[this._shadowCount.Value];
this._shadowPaints = new Paint[this._shadowCount.Value];
for (int index = 0; index < this._shadowCount.Value; index += 1) {
this._shadowPaints[index] = this._decoration.shadows[index].toPaint();
}
}
for (int index = 0; index < this._shadowCount; index += 1) {
BoxShadow shadow = this._decoration.shadows[index];
this._shadowPaths[index] = this._decoration.shape.getOuterPath(
rect.shift(shadow.offset).inflate(shadow.spreadRadius));
}
}
if (this._interiorPaint != null || this._shadowCount != null) {
this._outerPath = this._decoration.shape.getOuterPath(rect);
}
if (this._decoration.image != null) {
this._innerPath = this._decoration.shape.getInnerPath(rect);
}
this._lastRect = rect;
}
void _paintShadows(Canvas canvas) {
if (this._shadowCount != null) {
for (int index = 0; index < this._shadowCount.Value; index += 1) {
canvas.drawPath(this._shadowPaths[index], this._shadowPaints[index]);
}
}
}
void _paintInterior(Canvas canvas) {
if (this._interiorPaint != null) {
canvas.drawPath(this._outerPath, this._interiorPaint);
}
}
DecorationImagePainter _imagePainter;
void _paintImage(Canvas canvas, ImageConfiguration configuration) {
if (this._decoration.image == null) {
return;
}
this._imagePainter = this._imagePainter ?? this._decoration.image.createPainter(this.onChanged);
this._imagePainter.paint(canvas, this._lastRect, this._innerPath, configuration);
}
public override void Dispose() {
this._imagePainter?.Dispose();
base.Dispose();
}
public override void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
D.assert(configuration != null);
D.assert(configuration.size != null);
Rect rect = offset & configuration.size;
this._precache(rect);
this._paintShadows(canvas);
this._paintInterior(canvas);
this._paintImage(canvas, configuration);
this._decoration.shape.paint(canvas, rect);
}
}
}