| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| |
| import 'dart:math' as math; |
| |
| import 'package:flutter/foundation.dart'; |
| |
| import 'basic_types.dart'; |
| import 'borders.dart'; |
| import 'edge_insets.dart'; |
| |
| /// A border that fits a circle within the available space. |
| /// |
| /// Typically used with [ShapeDecoration] to draw a circle. |
| /// |
| /// The [dimensions] assume that the border is being used in a square space. |
| /// When applied to a rectangular space, the border paints in the center of the |
| /// rectangle. |
| /// |
| /// See also: |
| /// |
| /// * [BorderSide], which is used to describe each side of the box. |
| /// * [Border], which, when used with [BoxDecoration], can also |
| /// describe a circle. |
| class CircleBorder extends OutlinedBorder { |
| /// Create a circle border. |
| /// |
| /// The [side] argument must not be null. |
| const CircleBorder({ BorderSide side = BorderSide.none }) : assert(side != null), super(side: side); |
| |
| @override |
| EdgeInsetsGeometry get dimensions { |
| return EdgeInsets.all(side.width); |
| } |
| |
| @override |
| ShapeBorder scale(double t) => CircleBorder(side: side.scale(t)); |
| |
| @override |
| ShapeBorder? lerpFrom(ShapeBorder? a, double t) { |
| if (a is CircleBorder) |
| return CircleBorder(side: BorderSide.lerp(a.side, side, t)); |
| return super.lerpFrom(a, t); |
| } |
| |
| @override |
| ShapeBorder? lerpTo(ShapeBorder? b, double t) { |
| if (b is CircleBorder) |
| return CircleBorder(side: BorderSide.lerp(side, b.side, t)); |
| return super.lerpTo(b, t); |
| } |
| |
| @override |
| Path getInnerPath(Rect rect, { TextDirection? textDirection }) { |
| return Path() |
| ..addOval(Rect.fromCircle( |
| center: rect.center, |
| radius: math.max(0.0, rect.shortestSide / 2.0 - side.width), |
| )); |
| } |
| |
| @override |
| Path getOuterPath(Rect rect, { TextDirection? textDirection }) { |
| return Path() |
| ..addOval(Rect.fromCircle( |
| center: rect.center, |
| radius: rect.shortestSide / 2.0, |
| )); |
| } |
| |
| @override |
| CircleBorder copyWith({ BorderSide? side }) { |
| return CircleBorder(side: side ?? this.side); |
| } |
| |
| @override |
| void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) { |
| switch (side.style) { |
| case BorderStyle.none: |
| break; |
| case BorderStyle.solid: |
| canvas.drawCircle(rect.center, (rect.shortestSide - side.width) / 2.0, side.toPaint()); |
| } |
| } |
| |
| @override |
| bool operator ==(Object other) { |
| if (other.runtimeType != runtimeType) |
| return false; |
| return other is CircleBorder |
| && other.side == side; |
| } |
| |
| @override |
| int get hashCode => side.hashCode; |
| |
| @override |
| String toString() { |
| return '${objectRuntimeType(this, 'CircleBorder')}($side)'; |
| } |
| } |