kg
6 年前
当前提交
8ccc89d6
共有 33 个文件被更改,包括 3836 次插入 和 585 次删除
-
106Runtime/painting/alignment.cs
-
47Runtime/painting/basic_types.cs
-
245Runtime/painting/border_radius.cs
-
459Runtime/painting/borders.cs
-
279Runtime/painting/box_border.cs
-
258Runtime/painting/box_decoration.cs
-
11Runtime/painting/box_fit.cs
-
58Runtime/painting/box_shadow.cs
-
5Runtime/painting/clip.cs
-
34Runtime/painting/decoration.cs
-
176Runtime/painting/decoration_image.cs
-
33Runtime/painting/edge_insets.cs
-
5Runtime/painting/gradient.cs
-
4Runtime/rendering/proxy_box.cs
-
49Runtime/rendering/stack.cs
-
531Runtime/ui/geometry.cs
-
30Runtime/ui/painting/painting.cs
-
617Runtime/ui/painting/path.cs
-
34Runtime/widgets/basic.cs
-
2Runtime/widgets/scroll_view.cs
-
23Tests/Editor/CanvasAndLayers.cs
-
34Tests/Editor/RenderBoxes.cs
-
4Tests/Editor/Widgets.cs
-
146Runtime/painting/beveled_rectangle_border.cs
-
11Runtime/painting/beveled_rectangle_border.cs.meta
-
101Runtime/painting/circle_border.cs
-
11Runtime/painting/circle_border.cs.meta
-
331Runtime/painting/rounded_rectangle_border.cs
-
11Runtime/painting/rounded_rectangle_border.cs.meta
-
277Runtime/painting/shape_decoration.cs
-
11Runtime/painting/shape_decoration.cs.meta
-
467Runtime/painting/stadium_border.cs
-
11Runtime/painting/stadium_border.cs.meta
|
|||
namespace Unity.UIWidgets.painting { |
|||
public abstract class Gradient { |
|||
public abstract Gradient scale(double factor); |
|||
|
|||
public static Gradient lerp(Gradient a, Gradient b, double t) { |
|||
return null; |
|||
} |
|||
} |
|||
} |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.painting { |
|||
public class BeveledRectangleBorder : ShapeBorder, IEquatable<BeveledRectangleBorder> { |
|||
public BeveledRectangleBorder( |
|||
BorderSide side = null, |
|||
BorderRadius borderRadius = null |
|||
) { |
|||
this.side = side ?? BorderSide.none; |
|||
this.borderRadius = borderRadius ?? BorderRadius.zero; |
|||
} |
|||
|
|||
public readonly BorderSide side; |
|||
|
|||
public readonly BorderRadius borderRadius; |
|||
|
|||
public override EdgeInsets dimensions { |
|||
get { return EdgeInsets.all(this.side.width); } |
|||
} |
|||
|
|||
public override ShapeBorder scale(double t) { |
|||
return new BeveledRectangleBorder( |
|||
side: this.side.scale(t), |
|||
borderRadius: this.borderRadius * t |
|||
); |
|||
} |
|||
|
|||
public override ShapeBorder lerpFrom(ShapeBorder a, double t) { |
|||
if (a is BeveledRectangleBorder border) { |
|||
return new BeveledRectangleBorder( |
|||
side: BorderSide.lerp(border.side, this.side, t), |
|||
borderRadius: BorderRadius.lerp(border.borderRadius, this.borderRadius, t) |
|||
); |
|||
} |
|||
return base.lerpFrom(a, t); |
|||
} |
|||
|
|||
public override ShapeBorder lerpTo(ShapeBorder b, double t) { |
|||
if (b is BeveledRectangleBorder border) { |
|||
return new BeveledRectangleBorder( |
|||
side: BorderSide.lerp(this.side, border.side, t), |
|||
borderRadius: BorderRadius.lerp(this.borderRadius, border.borderRadius, t) |
|||
); |
|||
} |
|||
return base.lerpTo(b, t); |
|||
} |
|||
|
|||
Path _getPath(RRect rrect) { |
|||
Offset centerLeft = new Offset(rrect.left, rrect.center.dy); |
|||
Offset centerRight = new Offset(rrect.right, rrect.center.dy); |
|||
Offset centerTop = new Offset(rrect.center.dx, rrect.top); |
|||
Offset centerBottom = new Offset(rrect.center.dx, rrect.bottom); |
|||
|
|||
double tlRadiusX = Math.Max(0.0, rrect.tlRadiusX); |
|||
double tlRadiusY = Math.Max(0.0, rrect.tlRadiusY); |
|||
double trRadiusX = Math.Max(0.0, rrect.trRadiusX); |
|||
double trRadiusY = Math.Max(0.0, rrect.trRadiusY); |
|||
double blRadiusX = Math.Max(0.0, rrect.blRadiusX); |
|||
double blRadiusY = Math.Max(0.0, rrect.blRadiusY); |
|||
double brRadiusX = Math.Max(0.0, rrect.brRadiusX); |
|||
double brRadiusY = Math.Max(0.0, rrect.brRadiusY); |
|||
|
|||
List<Offset> vertices = new List<Offset> { |
|||
new Offset(rrect.left, Math.Min(centerLeft.dy, rrect.top + tlRadiusY)), |
|||
new Offset(Math.Min(centerTop.dx, rrect.left + tlRadiusX), rrect.top), |
|||
new Offset(Math.Max(centerTop.dx, rrect.right - trRadiusX), rrect.top), |
|||
new Offset(rrect.right, Math.Min(centerRight.dy, rrect.top + trRadiusY)), |
|||
new Offset(rrect.right, Math.Max(centerRight.dy, rrect.bottom - brRadiusY)), |
|||
new Offset(Math.Max(centerBottom.dx, rrect.right - brRadiusX), rrect.bottom), |
|||
new Offset(Math.Min(centerBottom.dx, rrect.left + blRadiusX), rrect.bottom), |
|||
new Offset(rrect.left, Math.Max(centerLeft.dy, rrect.bottom - blRadiusY)), |
|||
}; |
|||
|
|||
var path = new Path(); |
|||
path.addPolygon(vertices, true); |
|||
return path; |
|||
} |
|||
|
|||
public override Path getInnerPath(Rect rect) { |
|||
return this._getPath(this.borderRadius.toRRect(rect).deflate(this.side.width)); |
|||
} |
|||
|
|||
public override Path getOuterPath(Rect rect) { |
|||
return this._getPath(this.borderRadius.toRRect(rect)); |
|||
} |
|||
|
|||
public override void paint(Canvas canvas, Rect rect) { |
|||
if (rect.isEmpty) { |
|||
return; |
|||
} |
|||
switch (this.side.style) { |
|||
case BorderStyle.none: |
|||
break; |
|||
case BorderStyle.solid: |
|||
Path path = this.getOuterPath(rect); |
|||
path.addPath(this.getInnerPath(rect), Offset.zero); |
|||
canvas.drawPath(path, this.side.toPaint()); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public bool Equals(BeveledRectangleBorder other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
return Equals(this.side, other.side) && Equals(this.borderRadius, other.borderRadius); |
|||
} |
|||
|
|||
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((BeveledRectangleBorder) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
unchecked { |
|||
return ((this.side != null ? this.side.GetHashCode() : 0) * 397) ^ |
|||
(this.borderRadius != null ? this.borderRadius.GetHashCode() : 0); |
|||
} |
|||
} |
|||
|
|||
public static bool operator ==(BeveledRectangleBorder left, BeveledRectangleBorder right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(BeveledRectangleBorder left, BeveledRectangleBorder right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return $"{this.GetType()}({this.side}, {this.borderRadius})"; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 2efce6cbad99f4e5bbfd9e4b46eaae48 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.painting { |
|||
public class CircleBorder : ShapeBorder, IEquatable<CircleBorder> { |
|||
public CircleBorder(BorderSide side = null) { |
|||
this.side = side ?? BorderSide.none; |
|||
} |
|||
|
|||
public readonly BorderSide side; |
|||
|
|||
public override EdgeInsets dimensions { |
|||
get { return EdgeInsets.all(this.side.width); } |
|||
} |
|||
|
|||
public override ShapeBorder scale(double t) { |
|||
return new CircleBorder(side: this.side.scale(t)); |
|||
} |
|||
|
|||
public override ShapeBorder lerpFrom(ShapeBorder a, double t) { |
|||
if (a is CircleBorder border) { |
|||
return new CircleBorder(side: BorderSide.lerp(border.side, this.side, t)); |
|||
} |
|||
return base.lerpFrom(a, t); |
|||
} |
|||
|
|||
public override ShapeBorder lerpTo(ShapeBorder b, double t) { |
|||
if (b is CircleBorder border) { |
|||
return new CircleBorder(side: BorderSide.lerp(this.side, border.side, t)); |
|||
} |
|||
return base.lerpTo(b, t); |
|||
} |
|||
|
|||
public override Path getInnerPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addOval(Rect.fromCircle( |
|||
center: rect.center, |
|||
radius: Math.Max(0.0, rect.shortestSide / 2.0 - this.side.width) |
|||
)); |
|||
return path; |
|||
} |
|||
|
|||
public override Path getOuterPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addOval(Rect.fromCircle( |
|||
center: rect.center, |
|||
radius: rect.shortestSide / 2.0 |
|||
)); |
|||
return path; |
|||
} |
|||
|
|||
public override void paint(Canvas canvas, Rect rect) { |
|||
switch (this.side.style) { |
|||
case BorderStyle.none: |
|||
break; |
|||
case BorderStyle.solid: |
|||
canvas.drawCircle(rect.center, (rect.shortestSide - this.side.width) / 2.0, this.side.toPaint()); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public bool Equals(CircleBorder other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
return Equals(this.side, other.side); |
|||
} |
|||
|
|||
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((CircleBorder) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
return (this.side != null ? this.side.GetHashCode() : 0); |
|||
} |
|||
|
|||
public static bool operator ==(CircleBorder left, CircleBorder right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(CircleBorder left, CircleBorder right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return $"{this.GetType()}({this.side})"; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: a4d8740d6f8e64bd5bbe86f67d3019b7 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.painting { |
|||
public class RoundedRectangleBorder : ShapeBorder, IEquatable<RoundedRectangleBorder> { |
|||
public RoundedRectangleBorder( |
|||
BorderSide side = null, |
|||
BorderRadius borderRadius = null |
|||
) { |
|||
this.side = side ?? BorderSide.none; |
|||
this.borderRadius = borderRadius ?? BorderRadius.zero; |
|||
} |
|||
|
|||
public readonly BorderSide side; |
|||
|
|||
public readonly BorderRadius borderRadius; |
|||
|
|||
|
|||
public override EdgeInsets dimensions { |
|||
get { return EdgeInsets.all(this.side.width); } |
|||
} |
|||
|
|||
public override ShapeBorder scale(double t) { |
|||
return new RoundedRectangleBorder( |
|||
side: this.side.scale(t), |
|||
borderRadius: this.borderRadius * t |
|||
); |
|||
} |
|||
|
|||
public override ShapeBorder lerpFrom(ShapeBorder a, double t) { |
|||
if (a is RoundedRectangleBorder border) { |
|||
return new RoundedRectangleBorder( |
|||
side: BorderSide.lerp(border.side, this.side, t), |
|||
borderRadius: BorderRadius.lerp(border.borderRadius, this.borderRadius, t) |
|||
); |
|||
} |
|||
if (a is CircleBorder circleBorder) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: BorderSide.lerp(circleBorder.side, this.side, t), |
|||
borderRadius: this.borderRadius, |
|||
circleness: 1.0 - t |
|||
); |
|||
} |
|||
return base.lerpFrom(a, t); |
|||
} |
|||
|
|||
public override ShapeBorder lerpTo(ShapeBorder b, double t) { |
|||
if (b is RoundedRectangleBorder border) { |
|||
return new RoundedRectangleBorder( |
|||
side: BorderSide.lerp(this.side, border.side, t), |
|||
borderRadius: BorderRadius.lerp(this.borderRadius, border.borderRadius, t) |
|||
); |
|||
} |
|||
if (b is CircleBorder circleBorder) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: BorderSide.lerp(this.side, circleBorder.side, t), |
|||
borderRadius: this.borderRadius, |
|||
circleness: t |
|||
); |
|||
} |
|||
return base.lerpTo(b, t); |
|||
} |
|||
|
|||
public override Path getInnerPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addRRect(this.borderRadius.toRRect(rect).deflate(this.side.width)); |
|||
return path; |
|||
} |
|||
|
|||
public override Path getOuterPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addRRect(this.borderRadius.toRRect(rect)); |
|||
return path; |
|||
} |
|||
|
|||
public override void paint(Canvas canvas, Rect rect) { |
|||
switch (this.side.style) { |
|||
case BorderStyle.none: |
|||
break; |
|||
case BorderStyle.solid: |
|||
double width = this.side.width; |
|||
if (width == 0.0) { |
|||
canvas.drawRRect(this.borderRadius.toRRect(rect), this.side.toPaint()); |
|||
} else { |
|||
RRect outer = this.borderRadius.toRRect(rect); |
|||
RRect inner = outer.deflate(width); |
|||
Paint paint = new Paint { |
|||
color = this.side.color, |
|||
}; |
|||
canvas.drawDRRect(outer, inner, paint); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public bool Equals(RoundedRectangleBorder other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
return Equals(this.side, other.side) && Equals(this.borderRadius, other.borderRadius); |
|||
} |
|||
|
|||
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((RoundedRectangleBorder) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
unchecked { |
|||
return ((this.side != null ? this.side.GetHashCode() : 0) * 397) ^ |
|||
(this.borderRadius != null ? this.borderRadius.GetHashCode() : 0); |
|||
} |
|||
} |
|||
|
|||
public static bool operator ==(RoundedRectangleBorder left, RoundedRectangleBorder right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(RoundedRectangleBorder left, RoundedRectangleBorder right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return $"{this.GetType()}({this.side}, {this.borderRadius})"; |
|||
} |
|||
} |
|||
|
|||
class _RoundedRectangleToCircleBorder : ShapeBorder, IEquatable<_RoundedRectangleToCircleBorder> { |
|||
public _RoundedRectangleToCircleBorder( |
|||
BorderSide side = null, |
|||
BorderRadius borderRadius = null, |
|||
double circleness = 0.0 |
|||
) { |
|||
this.side = side ?? BorderSide.none; |
|||
this.borderRadius = borderRadius ?? BorderRadius.zero; |
|||
this.circleness = circleness; |
|||
} |
|||
|
|||
public readonly BorderSide side; |
|||
|
|||
public readonly BorderRadius borderRadius; |
|||
|
|||
public readonly double circleness; |
|||
|
|||
public override EdgeInsets dimensions { |
|||
get { return EdgeInsets.all(this.side.width); } |
|||
} |
|||
|
|||
public override ShapeBorder scale(double t) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: this.side.scale(t), |
|||
borderRadius: this.borderRadius * t, |
|||
circleness: t |
|||
); |
|||
} |
|||
|
|||
public override ShapeBorder lerpFrom(ShapeBorder a, double t) { |
|||
if (a is RoundedRectangleBorder rectBorder) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: BorderSide.lerp(rectBorder.side, this.side, t), |
|||
borderRadius: BorderRadius.lerp(rectBorder.borderRadius, this.borderRadius, t), |
|||
circleness: this.circleness * t |
|||
); |
|||
} |
|||
if (a is CircleBorder circleBorder) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: BorderSide.lerp(circleBorder.side, this.side, t), |
|||
borderRadius: this.borderRadius, |
|||
circleness: this.circleness + (1.0 - this.circleness) * (1.0 - t) |
|||
); |
|||
} |
|||
if (a is _RoundedRectangleToCircleBorder border) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: BorderSide.lerp(border.side, this.side, t), |
|||
borderRadius: BorderRadius.lerp(border.borderRadius, this.borderRadius, t), |
|||
circleness: MathUtils.lerpDouble(border.circleness, this.circleness, t) |
|||
); |
|||
} |
|||
return base.lerpFrom(a, t); |
|||
} |
|||
|
|||
public override ShapeBorder lerpTo(ShapeBorder b, double t) { |
|||
if (b is RoundedRectangleBorder rectBorder) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: BorderSide.lerp(this.side, rectBorder.side, t), |
|||
borderRadius: BorderRadius.lerp(this.borderRadius, rectBorder.borderRadius, t), |
|||
circleness: this.circleness * (1.0 - t) |
|||
); |
|||
} |
|||
if (b is CircleBorder circleBorder) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: BorderSide.lerp(this.side, circleBorder.side, t), |
|||
borderRadius: this.borderRadius, |
|||
circleness: this.circleness + (1.0 - this.circleness) * t |
|||
); |
|||
} |
|||
if (b is _RoundedRectangleToCircleBorder border) { |
|||
return new _RoundedRectangleToCircleBorder( |
|||
side: BorderSide.lerp(this.side, border.side, t), |
|||
borderRadius: BorderRadius.lerp(this.borderRadius, border.borderRadius, t), |
|||
circleness: MathUtils.lerpDouble(this.circleness, border.circleness, t) |
|||
); |
|||
} |
|||
return base.lerpTo(b, t); |
|||
} |
|||
|
|||
Rect _adjustRect(Rect rect) { |
|||
if (this.circleness == 0.0 || rect.width == rect.height) { |
|||
return rect; |
|||
} |
|||
|
|||
if (rect.width < rect.height) { |
|||
double delta = this.circleness * (rect.height - rect.width) / 2.0; |
|||
return Rect.fromLTRB( |
|||
rect.left, |
|||
rect.top + delta, |
|||
rect.right, |
|||
rect.bottom - delta |
|||
); |
|||
} else { |
|||
double delta = this.circleness * (rect.width - rect.height) / 2.0; |
|||
return Rect.fromLTRB( |
|||
rect.left + delta, |
|||
rect.top, |
|||
rect.right - delta, |
|||
rect.bottom |
|||
); |
|||
} |
|||
} |
|||
|
|||
BorderRadius _adjustBorderRadius(Rect rect) { |
|||
BorderRadius resolvedRadius = this.borderRadius; |
|||
if (this.circleness == 0.0) { |
|||
return resolvedRadius; |
|||
} |
|||
|
|||
return BorderRadius.lerp(resolvedRadius, BorderRadius.circular(rect.shortestSide / 2.0), this.circleness); |
|||
} |
|||
|
|||
public override Path getInnerPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addRRect(this._adjustBorderRadius(rect).toRRect(this._adjustRect(rect)).deflate(this.side.width)); |
|||
return path; |
|||
} |
|||
|
|||
public override Path getOuterPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addRRect(this._adjustBorderRadius(rect).toRRect(this._adjustRect(rect))); |
|||
return path; |
|||
} |
|||
|
|||
public override void paint(Canvas canvas, Rect rect) { |
|||
switch (this.side.style) { |
|||
case BorderStyle.none: |
|||
break; |
|||
case BorderStyle.solid: |
|||
double width = this.side.width; |
|||
if (width == 0.0) { |
|||
canvas.drawRRect(this._adjustBorderRadius(rect).toRRect(this._adjustRect(rect)), |
|||
this.side.toPaint()); |
|||
} else { |
|||
RRect outer = this._adjustBorderRadius(rect).toRRect(this._adjustRect(rect)); |
|||
RRect inner = outer.deflate(width); |
|||
Paint paint = new Paint { |
|||
color = this.side.color, |
|||
}; |
|||
canvas.drawDRRect(outer, inner, paint); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public bool Equals(_RoundedRectangleToCircleBorder other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
return Equals(this.side, other.side) && Equals(this.borderRadius, other.borderRadius) && |
|||
this.circleness.Equals(other.circleness); |
|||
} |
|||
|
|||
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((_RoundedRectangleToCircleBorder) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
unchecked { |
|||
var hashCode = (this.side != null ? this.side.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ (this.borderRadius != null ? this.borderRadius.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ this.circleness.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
public static bool operator ==(_RoundedRectangleToCircleBorder left, _RoundedRectangleToCircleBorder right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(_RoundedRectangleToCircleBorder left, _RoundedRectangleToCircleBorder right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return $"RoundedRectangleBorder({this.side}, {this.borderRadius}, " + |
|||
$"{this.circleness * 100:F1}% of the way to being a CircleBorder)"; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 72dec4218f16947789f8e842bc7aef5a |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 42721d35952224e5aac8229d0f85940a |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.painting { |
|||
public class StadiumBorder : ShapeBorder, IEquatable<StadiumBorder> { |
|||
public StadiumBorder(BorderSide side = null) { |
|||
this.side = side ?? BorderSide.none; |
|||
} |
|||
|
|||
public readonly BorderSide side; |
|||
|
|||
public override EdgeInsets dimensions { |
|||
get { return EdgeInsets.all(this.side.width); } |
|||
} |
|||
|
|||
public override ShapeBorder scale(double t) { |
|||
return new StadiumBorder(side: this.side.scale(t)); |
|||
} |
|||
|
|||
public override ShapeBorder lerpFrom(ShapeBorder a, double t) { |
|||
if (a is StadiumBorder stadiumBorder) { |
|||
return new StadiumBorder(side: BorderSide.lerp(stadiumBorder.side, this.side, t)); |
|||
} |
|||
if (a is CircleBorder circleBorder) { |
|||
return new _StadiumToCircleBorder( |
|||
side: BorderSide.lerp(circleBorder.side, this.side, t), |
|||
circleness: 1.0 - t |
|||
); |
|||
} |
|||
if (a is RoundedRectangleBorder rectBorder) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: BorderSide.lerp(rectBorder.side, this.side, t), |
|||
borderRadius: rectBorder.borderRadius, |
|||
rectness: 1.0 - t |
|||
); |
|||
} |
|||
return base.lerpFrom(a, t); |
|||
} |
|||
|
|||
public override ShapeBorder lerpTo(ShapeBorder b, double t) { |
|||
if (b is StadiumBorder stadiumBorder) { |
|||
return new StadiumBorder(side: BorderSide.lerp(this.side, stadiumBorder.side, t)); |
|||
} |
|||
|
|||
if (b is CircleBorder circleBorder) { |
|||
return new _StadiumToCircleBorder( |
|||
side: BorderSide.lerp(this.side, circleBorder.side, t), |
|||
circleness: t |
|||
); |
|||
} |
|||
if (b is RoundedRectangleBorder rectBorder) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: BorderSide.lerp(this.side, rectBorder.side, t), |
|||
borderRadius: rectBorder.borderRadius, |
|||
rectness: t |
|||
); |
|||
} |
|||
return base.lerpTo(b, t); |
|||
} |
|||
|
|||
public override Path getInnerPath(Rect rect) { |
|||
Radius radius = Radius.circular(rect.shortestSide / 2.0); |
|||
var path = new Path(); |
|||
path.addRRect(RRect.fromRectAndRadius(rect, radius).deflate(this.side.width)); |
|||
return path; |
|||
} |
|||
|
|||
public override Path getOuterPath(Rect rect) { |
|||
Radius radius = Radius.circular(rect.shortestSide / 2.0); |
|||
var path = new Path(); |
|||
path.addRRect(RRect.fromRectAndRadius(rect, radius)); |
|||
return path; |
|||
} |
|||
|
|||
public override void paint(Canvas canvas, Rect rect) { |
|||
switch (this.side.style) { |
|||
case BorderStyle.none: |
|||
break; |
|||
case BorderStyle.solid: |
|||
Radius radius = Radius.circular(rect.shortestSide / 2.0); |
|||
canvas.drawRRect( |
|||
RRect.fromRectAndRadius(rect, radius).deflate(this.side.width / 2.0), |
|||
this.side.toPaint() |
|||
); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public bool Equals(StadiumBorder other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
return Equals(this.side, other.side); |
|||
} |
|||
|
|||
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((StadiumBorder) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
return (this.side != null ? this.side.GetHashCode() : 0); |
|||
} |
|||
|
|||
public static bool operator ==(StadiumBorder left, StadiumBorder right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(StadiumBorder left, StadiumBorder right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return $"{this.GetType()}({this.side})"; |
|||
} |
|||
} |
|||
|
|||
class _StadiumToCircleBorder : ShapeBorder, IEquatable<_StadiumToCircleBorder> { |
|||
public _StadiumToCircleBorder( |
|||
BorderSide side = null, |
|||
double circleness = 0.0 |
|||
) { |
|||
this.side = BorderSide.none; |
|||
this.circleness = circleness; |
|||
} |
|||
|
|||
public readonly BorderSide side; |
|||
|
|||
public readonly double circleness; |
|||
|
|||
public override EdgeInsets dimensions { |
|||
get { return EdgeInsets.all(this.side.width); } |
|||
} |
|||
|
|||
public override ShapeBorder scale(double t) { |
|||
return new _StadiumToCircleBorder( |
|||
side: this.side.scale(t), |
|||
circleness: t |
|||
); |
|||
} |
|||
|
|||
public override ShapeBorder lerpFrom(ShapeBorder a, double t) { |
|||
if (a is StadiumBorder stadiumBorder) { |
|||
return new _StadiumToCircleBorder( |
|||
side: BorderSide.lerp(stadiumBorder.side, this.side, t), |
|||
circleness: this.circleness * t |
|||
); |
|||
} |
|||
if (a is CircleBorder circleBorder) { |
|||
return new _StadiumToCircleBorder( |
|||
side: BorderSide.lerp(circleBorder.side, this.side, t), |
|||
circleness: this.circleness + (1.0 - this.circleness) * (1.0 - t) |
|||
); |
|||
} |
|||
if (a is _StadiumToCircleBorder border) { |
|||
return new _StadiumToCircleBorder( |
|||
side: BorderSide.lerp(border.side, this.side, t), |
|||
circleness: MathUtils.lerpDouble(border.circleness, this.circleness, t) |
|||
); |
|||
} |
|||
return base.lerpFrom(a, t); |
|||
} |
|||
|
|||
public override ShapeBorder lerpTo(ShapeBorder b, double t) { |
|||
if (b is StadiumBorder stadiumBorder) { |
|||
return new _StadiumToCircleBorder( |
|||
side: BorderSide.lerp(this.side, stadiumBorder.side, t), |
|||
circleness: this.circleness * (1.0 - t) |
|||
); |
|||
} |
|||
if (b is CircleBorder circleBorder) { |
|||
return new _StadiumToCircleBorder( |
|||
side: BorderSide.lerp(this.side, circleBorder.side, t), |
|||
circleness: this.circleness + (1.0 - this.circleness) * t |
|||
); |
|||
} |
|||
if (b is _StadiumToCircleBorder border) { |
|||
return new _StadiumToCircleBorder( |
|||
side: BorderSide.lerp(this.side, border.side, t), |
|||
circleness: MathUtils.lerpDouble(this.circleness, border.circleness, t) |
|||
); |
|||
} |
|||
return base.lerpTo(b, t); |
|||
} |
|||
|
|||
Rect _adjustRect(Rect rect) { |
|||
if (this.circleness == 0.0 || rect.width == rect.height) { |
|||
return rect; |
|||
} |
|||
if (rect.width < rect.height) { |
|||
double delta = this.circleness * (rect.height - rect.width) / 2.0; |
|||
return Rect.fromLTRB( |
|||
rect.left, |
|||
rect.top + delta, |
|||
rect.right, |
|||
rect.bottom - delta |
|||
); |
|||
} else { |
|||
double delta = this.circleness * (rect.width - rect.height) / 2.0; |
|||
return Rect.fromLTRB( |
|||
rect.left + delta, |
|||
rect.top, |
|||
rect.right - delta, |
|||
rect.bottom |
|||
); |
|||
} |
|||
} |
|||
|
|||
BorderRadius _adjustBorderRadius(Rect rect) { |
|||
return BorderRadius.circular(rect.shortestSide / 2.0); |
|||
} |
|||
|
|||
public override Path getInnerPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addRRect(this._adjustBorderRadius(rect).toRRect(this._adjustRect(rect)).deflate(this.side.width)); |
|||
return path; |
|||
} |
|||
|
|||
public override Path getOuterPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addRRect(this._adjustBorderRadius(rect).toRRect(this._adjustRect(rect))); |
|||
return path; |
|||
} |
|||
|
|||
public override void paint(Canvas canvas, Rect rect) { |
|||
switch (this.side.style) { |
|||
case BorderStyle.none: |
|||
break; |
|||
case BorderStyle.solid: |
|||
double width = this.side.width; |
|||
if (width == 0.0) { |
|||
canvas.drawRRect(this._adjustBorderRadius(rect).toRRect(this._adjustRect(rect)), |
|||
this.side.toPaint()); |
|||
} else { |
|||
RRect outer = this._adjustBorderRadius(rect).toRRect(this._adjustRect(rect)); |
|||
RRect inner = outer.deflate(width); |
|||
Paint paint = new Paint { |
|||
color = this.side.color, |
|||
}; |
|||
canvas.drawDRRect(outer, inner, paint); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public bool Equals(_StadiumToCircleBorder other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
return Equals(this.side, other.side) && this.circleness.Equals(other.circleness); |
|||
} |
|||
|
|||
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((_StadiumToCircleBorder) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
unchecked { |
|||
return ((this.side != null ? this.side.GetHashCode() : 0) * 397) ^ this.circleness.GetHashCode(); |
|||
} |
|||
} |
|||
|
|||
public static bool operator ==(_StadiumToCircleBorder left, _StadiumToCircleBorder right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(_StadiumToCircleBorder left, _StadiumToCircleBorder right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return $"StadiumBorder($side, {this.circleness * 100:F1}% " + |
|||
"of the way to being a CircleBorder)"; |
|||
} |
|||
} |
|||
|
|||
class _StadiumToRoundedRectangleBorder : ShapeBorder, IEquatable<_StadiumToRoundedRectangleBorder> { |
|||
public _StadiumToRoundedRectangleBorder( |
|||
BorderSide side = null, |
|||
BorderRadius borderRadius = null, |
|||
double rectness = 0.0 |
|||
) { |
|||
this.side = side ?? BorderSide.none; |
|||
this.borderRadius = borderRadius ?? BorderRadius.zero; |
|||
this.rectness = rectness; |
|||
} |
|||
|
|||
public readonly BorderSide side; |
|||
|
|||
public readonly BorderRadius borderRadius; |
|||
|
|||
public readonly double rectness; |
|||
|
|||
public override EdgeInsets dimensions { |
|||
get { return EdgeInsets.all(this.side.width); } |
|||
} |
|||
|
|||
public override ShapeBorder scale(double t) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: this.side.scale(t), |
|||
borderRadius: this.borderRadius * t, |
|||
rectness: t |
|||
); |
|||
} |
|||
|
|||
public override ShapeBorder lerpFrom(ShapeBorder a, double t) { |
|||
if (a is StadiumBorder stadiumBorder) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: BorderSide.lerp(stadiumBorder.side, this.side, t), |
|||
borderRadius: this.borderRadius, |
|||
rectness: this.rectness * t |
|||
); |
|||
} |
|||
if (a is RoundedRectangleBorder rectBorder) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: BorderSide.lerp(rectBorder.side, this.side, t), |
|||
borderRadius: this.borderRadius, |
|||
rectness: this.rectness + (1.0 - this.rectness) * (1.0 - t) |
|||
); |
|||
} |
|||
if (a is _StadiumToRoundedRectangleBorder border) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: BorderSide.lerp(border.side, this.side, t), |
|||
borderRadius: BorderRadius.lerp(border.borderRadius, this.borderRadius, t), |
|||
rectness: MathUtils.lerpDouble(border.rectness, this.rectness, t) |
|||
); |
|||
} |
|||
return base.lerpFrom(a, t); |
|||
} |
|||
|
|||
public override ShapeBorder lerpTo(ShapeBorder b, double t) { |
|||
if (b is StadiumBorder stadiumBorder) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: BorderSide.lerp(this.side, stadiumBorder.side, t), |
|||
borderRadius: this.borderRadius, |
|||
rectness: this.rectness * (1.0 - t) |
|||
); |
|||
} |
|||
if (b is RoundedRectangleBorder rectBorder) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: BorderSide.lerp(this.side, rectBorder.side, t), |
|||
borderRadius: this.borderRadius, |
|||
rectness: this.rectness + (1.0 - this.rectness) * t |
|||
); |
|||
} |
|||
if (b is _StadiumToRoundedRectangleBorder border) { |
|||
return new _StadiumToRoundedRectangleBorder( |
|||
side: BorderSide.lerp(this.side, border.side, t), |
|||
borderRadius: BorderRadius.lerp(this.borderRadius, border.borderRadius, t), |
|||
rectness: MathUtils.lerpDouble(this.rectness, border.rectness, t) |
|||
); |
|||
} |
|||
return base.lerpTo(b, t); |
|||
} |
|||
|
|||
BorderRadius _adjustBorderRadius(Rect rect) { |
|||
return BorderRadius.lerp( |
|||
this.borderRadius, |
|||
BorderRadius.all(Radius.circular(rect.shortestSide / 2.0)), |
|||
1.0 - this.rectness |
|||
); |
|||
} |
|||
|
|||
public override Path getInnerPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addRRect(this._adjustBorderRadius(rect).toRRect(rect).deflate(this.side.width)); |
|||
return path; |
|||
} |
|||
|
|||
public override Path getOuterPath(Rect rect) { |
|||
var path = new Path(); |
|||
path.addRRect(this._adjustBorderRadius(rect).toRRect(rect)); |
|||
return path; |
|||
} |
|||
|
|||
public override void paint(Canvas canvas, Rect rect) { |
|||
switch (this.side.style) { |
|||
case BorderStyle.none: |
|||
break; |
|||
case BorderStyle.solid: |
|||
double width = this.side.width; |
|||
if (width == 0.0) { |
|||
canvas.drawRRect(this._adjustBorderRadius(rect).toRRect(rect), this.side.toPaint()); |
|||
} else { |
|||
RRect outer = this._adjustBorderRadius(rect).toRRect(rect); |
|||
RRect inner = outer.deflate(width); |
|||
Paint paint = new Paint { |
|||
color = this.side.color, |
|||
}; |
|||
canvas.drawDRRect(outer, inner, paint); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public bool Equals(_StadiumToRoundedRectangleBorder other) { |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
return Equals(this.side, other.side) && Equals(this.borderRadius, other.borderRadius) && |
|||
this.rectness.Equals(other.rectness); |
|||
} |
|||
|
|||
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((_StadiumToRoundedRectangleBorder) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() { |
|||
unchecked { |
|||
var hashCode = (this.side != null ? this.side.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ (this.borderRadius != null ? this.borderRadius.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ this.rectness.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
public static bool operator ==(_StadiumToRoundedRectangleBorder left, _StadiumToRoundedRectangleBorder right) { |
|||
return Equals(left, right); |
|||
} |
|||
|
|||
public static bool operator !=(_StadiumToRoundedRectangleBorder left, _StadiumToRoundedRectangleBorder right) { |
|||
return !Equals(left, right); |
|||
} |
|||
|
|||
|
|||
public override string ToString() { |
|||
return $"StadiumBorder({this.side}, {this.borderRadius}, " + |
|||
$"{this.rectness * 100:F1}% of the way to being a " + |
|||
"RoundedRectangleBorder)"; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: cf6d45cec381142ada29150ceb442783 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue