Line data Source code
1 : // Copyright 2014 The Flutter Authors.
2 : // Copyright 2021 Suragch.
3 : // All rights reserved.
4 : // Use of this source code is governed by a BSD-style license that can be
5 : // found in the LICENSE file.
6 :
7 : import 'dart:ui';
8 : import 'dart:math' as math;
9 :
10 : import 'package:flutter/material.dart'
11 : show
12 : InputBorder,
13 : BorderSide,
14 : BorderRadius,
15 : Radius,
16 : EdgeInsetsGeometry,
17 : EdgeInsets,
18 : ShapeBorder;
19 :
20 : /// Draws a vertical line at the right side of a [MongolInputDecorator]'s
21 : /// container and defines the container's shape.
22 : ///
23 : /// The input decorator's "container" is the optionally filled area to the left
24 : /// of the decorator's helper, error, and counter.
25 : ///
26 : /// See also:
27 : ///
28 : /// * [OutlineInputBorder], an [InputDecorator] border which draws a
29 : /// rounded rectangle around the input decorator's container.
30 : /// * [MongolInputDecoration], which is used to configure a
31 : /// [MongolInputDecorator].
32 : class SidelineInputBorder extends InputBorder {
33 : /// Creates a single line border on the right for a [MongolInputDecorator].
34 : ///
35 : /// The [borderSide] parameter defaults to [BorderSide.none] (it must not be
36 : /// null). Applications typically do not specify a [borderSide] parameter
37 : /// because the input decorator substitutes its own, using [copyWith], based
38 : /// on the current theme and [MongolInputDecorator.isFocused].
39 : ///
40 : /// The [borderRadius] parameter defaults to a value where the top and
41 : /// bottom left corners have a circular radius of 4.0. The [borderRadius]
42 : /// parameter must not be null.
43 9 : const SidelineInputBorder({
44 : BorderSide borderSide = const BorderSide(),
45 : this.borderRadius = const BorderRadius.only(
46 : topLeft: Radius.circular(4.0),
47 : bottomLeft: Radius.circular(4.0),
48 : ),
49 1 : }) : super(borderSide: borderSide);
50 :
51 : /// The radii of the border's rounded rectangle corners.
52 : ///
53 : /// When this border is used with a filled input decorator, see
54 : /// [MongolInputDecoration.filled], the border radius defines the shape
55 : /// of the background fill as well as the top and bottom right
56 : /// edges of the sideline itself.
57 : ///
58 : /// By default the top and bottom left corners have a circular radius
59 : /// of 4.0.
60 : final BorderRadius borderRadius;
61 :
62 1 : @override
63 : bool get isOutline => false;
64 :
65 1 : @override
66 : SidelineInputBorder copyWith(
67 : {BorderSide? borderSide, BorderRadius? borderRadius}) {
68 1 : return SidelineInputBorder(
69 0 : borderSide: borderSide ?? this.borderSide,
70 1 : borderRadius: borderRadius ?? this.borderRadius,
71 : );
72 : }
73 :
74 0 : @override
75 : EdgeInsetsGeometry get dimensions {
76 0 : return EdgeInsets.only(right: borderSide.width);
77 : }
78 :
79 0 : @override
80 : SidelineInputBorder scale(double t) {
81 0 : return SidelineInputBorder(borderSide: borderSide.scale(t));
82 : }
83 :
84 0 : @override
85 : Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
86 0 : return Path()
87 0 : ..addRect(Rect.fromLTWH(rect.left, rect.top,
88 0 : math.max(0.0, rect.width - borderSide.width), rect.height));
89 : }
90 :
91 0 : @override
92 : Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
93 0 : return Path()..addRRect(borderRadius.toRRect(rect));
94 : }
95 :
96 1 : @override
97 : ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
98 1 : if (a is SidelineInputBorder) {
99 1 : return SidelineInputBorder(
100 3 : borderSide: BorderSide.lerp(a.borderSide, borderSide, t),
101 3 : borderRadius: BorderRadius.lerp(a.borderRadius, borderRadius, t)!,
102 : );
103 : }
104 0 : return super.lerpFrom(a, t);
105 : }
106 :
107 0 : @override
108 : ShapeBorder? lerpTo(ShapeBorder? b, double t) {
109 0 : if (b is SidelineInputBorder) {
110 0 : return SidelineInputBorder(
111 0 : borderSide: BorderSide.lerp(borderSide, b.borderSide, t),
112 0 : borderRadius: BorderRadius.lerp(borderRadius, b.borderRadius, t)!,
113 : );
114 : }
115 0 : return super.lerpTo(b, t);
116 : }
117 :
118 : /// Draw a vertical line at the right side of [rect].
119 : ///
120 : /// The [borderSide] defines the line's color and weight.
121 1 : @override
122 : void paint(
123 : Canvas canvas,
124 : Rect rect, {
125 : double? gapStart,
126 : double gapExtent = 0.0,
127 : double gapPercentage = 0.0,
128 : TextDirection? textDirection,
129 : }) {
130 3 : if (borderRadius.topRight != Radius.zero ||
131 3 : borderRadius.bottomRight != Radius.zero) {
132 0 : canvas.clipPath(getOuterPath(rect, textDirection: textDirection));
133 : }
134 5 : canvas.drawLine(rect.topRight, rect.bottomRight, borderSide.toPaint());
135 : }
136 :
137 1 : @override
138 : bool operator ==(Object other) {
139 : if (identical(this, other)) return true;
140 3 : if (other.runtimeType != runtimeType) return false;
141 4 : return other is InputBorder && other.borderSide == borderSide;
142 : }
143 :
144 0 : @override
145 0 : int get hashCode => borderSide.hashCode;
146 : }
|