Skip to content
This repository was archived by the owner on Apr 29, 2021. It is now read-only.

Commit 1478f5b

Browse files
authored
Merge pull request #187 from UnityTech/yczhang
Implement ClipOval
2 parents be59585 + 9fa0936 commit 1478f5b

File tree

2 files changed

+115
-16
lines changed

2 files changed

+115
-16
lines changed

Runtime/rendering/proxy_box.cs

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,69 @@ protected override void debugPaintSize(PaintingContext context, Offset offset) {
983983
}
984984
}
985985

986+
public class RenderClipOval : _RenderCustomClip<Rect> {
987+
public RenderClipOval(
988+
RenderBox child = null,
989+
CustomClipper<Rect> clipper = null,
990+
Clip clipBehavior = Clip.antiAlias
991+
) : base(child: child, clipper: clipper, clipBehavior: clipBehavior) {
992+
D.assert(clipBehavior != Clip.none);
993+
}
994+
995+
Rect _cachedRect;
996+
Path _cachedPath;
997+
998+
Path _getClipPath(Rect rect) {
999+
if (rect != this._cachedRect) {
1000+
this._cachedRect = rect;
1001+
this._cachedPath = new Path();
1002+
this._cachedPath.addOval(this._cachedRect);
1003+
}
1004+
1005+
return this._cachedPath;
1006+
}
1007+
1008+
protected override Rect _defaultClip {
1009+
get { return Offset.zero & this.size; }
1010+
}
1011+
1012+
public override bool hitTest(HitTestResult result,
1013+
Offset position = null
1014+
) {
1015+
this._updateClip();
1016+
D.assert(this._clip != null);
1017+
Offset center = this._clip.center;
1018+
Offset offset = new Offset((position.dx - center.dx) / this._clip.width,
1019+
(position.dy - center.dy) / this._clip.height);
1020+
if (offset.distanceSquared > 0.25f) {
1021+
return false;
1022+
}
1023+
1024+
return base.hitTest(result, position: position);
1025+
}
1026+
1027+
public override void paint(PaintingContext context, Offset offset) {
1028+
if (this.child != null) {
1029+
this._updateClip();
1030+
context.pushClipPath(this.needsCompositing, offset, this._clip, this._getClipPath(this._clip),
1031+
base.paint, clipBehavior: this.clipBehavior);
1032+
}
1033+
}
1034+
1035+
protected override void debugPaintSize(PaintingContext context, Offset offset) {
1036+
D.assert(() => {
1037+
if (this.child != null) {
1038+
base.debugPaintSize(context, offset);
1039+
context.canvas.drawPath(this._getClipPath(this._clip).shift(offset), this._debugPaint);
1040+
this._debugText.paint(context.canvas,
1041+
offset + new Offset((this._clip.width - this._debugText.width) / 2.0f,
1042+
-this._debugText.text.style.fontSize * 1.1f ?? 0.0f));
1043+
}
1044+
1045+
return true;
1046+
});
1047+
}
1048+
}
9861049

9871050
public class RenderClipPath : _RenderCustomClip<Path> {
9881051
public RenderClipPath(
@@ -1194,7 +1257,7 @@ public override bool hitTest(HitTestResult result, Offset position = null) {
11941257
return base.hitTest(result, position: position);
11951258
}
11961259

1197-
1260+
11981261
public override void paint(PaintingContext context, Offset offset) {
11991262
if (this.child != null) {
12001263
this._updateClip();
@@ -1282,7 +1345,7 @@ public override bool hitTest(HitTestResult result, Offset position = null) {
12821345
return base.hitTest(result, position: position);
12831346
}
12841347

1285-
1348+
12861349
public override void paint(PaintingContext context, Offset offset) {
12871350
if (this.child != null) {
12881351
this._updateClip();
@@ -1301,19 +1364,20 @@ public override void paint(PaintingContext context, Offset offset) {
13011364
}
13021365
else {
13031366
Canvas canvas = context.canvas;
1304-
if (this.elevation != 0.0) {
1305-
canvas.drawRect(
1306-
offsetBounds.inflate(20.0f),
1307-
_transparentPaint
1308-
);
1309-
1310-
canvas.drawShadow(
1311-
offsetPath,
1312-
this.shadowColor,
1313-
this.elevation,
1314-
this.color.alpha != 0xFF
1315-
);
1316-
}
1367+
if (this.elevation != 0.0) {
1368+
canvas.drawRect(
1369+
offsetBounds.inflate(20.0f),
1370+
_transparentPaint
1371+
);
1372+
1373+
canvas.drawShadow(
1374+
offsetPath,
1375+
this.shadowColor,
1376+
this.elevation,
1377+
this.color.alpha != 0xFF
1378+
);
1379+
}
1380+
13171381
Paint paint = new Paint {color = this.color, style = PaintingStyle.fill};
13181382
canvas.drawPath(offsetPath, paint);
13191383
context.clipPathAndPaint(offsetPath, this.clipBehavior,

Runtime/widgets/basic.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,41 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties)
194194
}
195195
}
196196

197+
public class ClipOval : SingleChildRenderObjectWidget {
198+
public ClipOval(
199+
Key key = null,
200+
CustomClipper<Rect> clipper = null,
201+
Clip clipBehavior = Clip.antiAlias,
202+
Widget child = null) : base(key: key, child: child
203+
) {
204+
this.clipper = clipper;
205+
this.clipBehavior = clipBehavior;
206+
}
207+
208+
public readonly CustomClipper<Rect> clipper;
209+
210+
public readonly Clip clipBehavior;
211+
212+
public override RenderObject createRenderObject(BuildContext context) {
213+
return new RenderClipOval(clipper: this.clipper, clipBehavior: this.clipBehavior);
214+
}
215+
216+
public override void updateRenderObject(BuildContext context, RenderObject _renderObject) {
217+
RenderClipOval renderObject = _renderObject as RenderClipOval;
218+
renderObject.clipper = this.clipper;
219+
}
220+
221+
public override void didUnmountRenderObject(RenderObject _renderObject) {
222+
RenderClipOval renderObject = _renderObject as RenderClipOval;
223+
renderObject.clipper = null;
224+
}
225+
226+
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
227+
base.debugFillProperties(properties);
228+
properties.add(new DiagnosticsProperty<CustomClipper<Rect>>("clipper", this.clipper, defaultValue: null));
229+
}
230+
}
231+
197232
public class ClipPath : SingleChildRenderObjectWidget {
198233
public ClipPath(
199234
Key key = null,
@@ -2161,4 +2196,4 @@ public override Widget build(BuildContext context) {
21612196
return this.builder(context);
21622197
}
21632198
}
2164-
}
2199+
}

0 commit comments

Comments
 (0)