diff --git a/example/lib/main.dart b/example/lib/main.dart index cc029e6a..7b616839 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -14,7 +14,6 @@ class MyApp extends StatelessWidget { ); } -// class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); diff --git a/example/pubspec.lock b/example/pubspec.lock index e43d136b..e69de29b 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,264 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.5.0-nullsafety" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety.2" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.15.0-nullsafety.2" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - url: "https://pub.dartlang.org" - source: hosted - version: "0.18.1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - getwidget: - dependency: "direct main" - description: - path: ".." - relative: true - source: path - version: "1.1.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.10-nullsafety" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0-nullsafety.2" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0-nullsafety" - path_drawing: - dependency: transitive - description: - name: path_drawing - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.1+1" - path_parsing: - dependency: transitive - description: - name: path_parsing - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.4" - platform_detect: - dependency: transitive - description: - name: platform_detect - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.4" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0-nullsafety" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0-nullsafety" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.19-nullsafety" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0-nullsafety.2" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - url: "https://pub.dartlang.org" - source: hosted - version: "5.5.3" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+1" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+7" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.8" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3+2" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.2" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" -sdks: - dart: ">=2.10.0-0.0.dev <2.10.0" - flutter: ">=1.18.0-6.0.pre <2.0.0" diff --git a/lib/components/border/gf_border.dart b/lib/components/border/gf_border.dart new file mode 100644 index 00000000..3f74b802 --- /dev/null +++ b/lib/components/border/gf_border.dart @@ -0,0 +1,76 @@ +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:getwidget/components/border/gf_dashed_border.dart'; +import 'package:getwidget/types/gf_border_type.dart'; + +class GFBorder extends StatelessWidget { + GFBorder({ + @required this.child, + this.color = Colors.black, + this.strokeWidth = 1, + this.type = GFBorderType.Rect, + this.dashedLine = const [3, 1], + this.padding = const EdgeInsets.all(10), + this.radius = const Radius.circular(0), + this.customPath, + }) : assert(child != null), + assert(_isValiddashedLine(dashedLine), 'Invalid dash pattern'); + + /// child of type [Widget] which can be any component or text , etc + final Widget child; + + /// padding of time [EdgeInsets] where in padding is given to the border types + final EdgeInsets padding; + + /// storkeWidth of type [double] which is used to define the thickness of the border + final double strokeWidth; + + /// color of type [Color] or GFColor which is used to change the color of the border type + final Color color; + + /// dashedLine of type [List] which is used for the linear and simple dashed line of border + final List dashedLine; + + /// type of [GFBorderType] which is used to define the different types of borders ie, circle, Rect, RRect and oval + final GFBorderType type; + + /// radius of type [Radius] used to give a curved border only when the border type is RRect, in other cases radius will not work + final Radius radius; + + /// customPath of type [PathBuilder] used for drawing the paths + final PathBuilder customPath; + + @override + Widget build(BuildContext context) => Stack( + children: [ + Positioned.fill( + child: CustomPaint( + painter: DashedType( + strokeWidth: strokeWidth, + radius: radius, + color: color, + type: type, + dashedLine: dashedLine, + customPath: customPath, + ), + ), + ), + Container(padding: padding, child: child), + ], + ); +} + +/// the value of dashedLine cannot be 0 or null, it should have some definite and proper value +bool _isValiddashedLine(List dash) { + final Set _dashSet = dash.toSet(); + if (_dashSet == null) { + return false; + } + if (_dashSet.length == 1 && _dashSet.elementAt(0) == 0.0) { + return false; + } + if (_dashSet.isEmpty) { + return false; + } + return true; +} diff --git a/lib/components/border/gf_dashed_border.dart b/lib/components/border/gf_dashed_border.dart new file mode 100644 index 00000000..fc56c3b8 --- /dev/null +++ b/lib/components/border/gf_dashed_border.dart @@ -0,0 +1,199 @@ +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:getwidget/types/gf_border_type.dart'; + +typedef PathBuilder = Path Function(Size); + +class DashedType extends CustomPainter { + DashedType({ + this.strokeWidth = 2, + this.dashedLine = const [3, 1], + this.color = Colors.black, + this.type = GFBorderType.Rect, + this.radius = const Radius.circular(0), + this.customPath, + }) : assert(dashedLine.isNotEmpty, 'dash line cannot be empty'); + + /// storkeWidth of type [double] which is used to define the thickness of the border + final double strokeWidth; + + /// dashedLine of type [List] which is used for the linear and simple dashed line of border + final List dashedLine; + + /// color of type [Color] or GFColor which is used to change the color of the border type + final Color color; + + /// type of [GFBorderType] which is used to define the different types of borders ie, circle, Rect, RRect and oval + final GFBorderType type; + + /// radius of type [Radius] used to give a curved border only when the border type is RRect, in other cases radius will not work + final Radius radius; + + /// customPath of type [PathBuilder] used for the drawing the paths + final PathBuilder customPath; + + @override + void paint(Canvas canvas, Size size) { + final Paint paint = Paint() + ..strokeWidth = strokeWidth + ..color = color + ..style = PaintingStyle.stroke; + + Path _path; + if (customPath != null) { + _path = dashPath( + customPath(size), + dashedarray: CircularIntervalList(dashedLine), + ); + } else { + _path = _getPath(size); + } + + canvas.drawPath(_path, paint); + } + + /// Returns a [Path] based on the the borderType parameter + Path _getPath(Size size) { + Path path; + switch (type) { + case GFBorderType.Circle: + path = _getCirclePath(size); + break; + case GFBorderType.RRect: + path = _getRRectPath(size, radius); + break; + case GFBorderType.Rect: + path = _getRectPath(size); + break; + case GFBorderType.Oval: + path = _getOvalPath(size); + break; + } + + return dashPath(path, dashedarray: CircularIntervalList(dashedLine)); + } + + /// gives a circular path of borderType + Path _getCirclePath(Size size) { + final double width = size.width; + final double height = size.height; + final double sizes = size.shortestSide; + + return Path() + ..addRRect( + RRect.fromRectAndRadius( + Rect.fromLTWH( + width > sizes ? (width - sizes) / 2 : 0, + height > sizes ? (height - sizes / 2) : 0, + sizes, + sizes, + ), + Radius.circular(sizes / 2), + ), + ); + } + + /// gives a Rounded Rectangular Path with [radius] of [size] for borderType + + Path _getRRectPath(Size size, Radius radius) => Path() + ..addRRect( + RRect.fromRectAndRadius( + Rect.fromLTWH( + 0, + 0, + size.width, + size.height, + ), + radius, + ), + ); + + /// gives a Rectangular Path with [size] for borderType + Path _getRectPath(Size size) => Path() + ..addRect( + Rect.fromLTWH( + 0, + 0, + size.width, + size.height, + ), + ); + + /// gives an oval path of [size] for borderType + Path _getOvalPath(Size size) => Path() + ..addOval( + Rect.fromLTWH( + 0, + 0, + size.width, + size.height, + ), + ); + + @override + bool shouldRepaint(DashedType oldDelegate) => + oldDelegate.strokeWidth != strokeWidth || + oldDelegate.color != color || + oldDelegate.dashedLine != dashedLine || + oldDelegate.type != type; +} + +class CircularIntervalList { + CircularIntervalList(this.values); + + final List values; + int index = 0; + + T get next { + if (index >= values.length) { + index = 0; + } + return values[index++]; + } +} + +Path dashPath(Path source, + {@required CircularIntervalList dashedarray, + DashOffset dashOffset = const DashOffset.absolute(0)}) { + assert(dashedarray != null); + if (source == null) { + return null; + } + + final Path dest = Path(); + for (final PathMetric metric in source.computeMetrics()) { + double distance = dashOffset._calculate(metric.length); + bool draw = true; + while (distance < metric.length) { + final double len = dashedarray.next; + if (draw) { + dest.addPath(metric.extractPath(distance, distance + len), Offset.zero); + } + distance += len; + draw = !draw; + } + } + + return dest; +} + +/// Specifies the starting position of a dashed array or line on a path, either as a percentage or absolute +enum _DashOffsetType { Absolute, Percentage } + +class DashOffset { + ///gives offset of the dashed path that will be measured as a percentage which ranges from 0.0 to 1.0 + DashOffset.percentage(double percentage) + : _value = percentage.clamp(0.0, 1.0) ?? 0.0, + _dashOffsetType = _DashOffsetType.Percentage; + + ///gives offset of the dashed path that will be measured as a absolute value + const DashOffset.absolute(double start) + : _value = start ?? 0.0, + _dashOffsetType = _DashOffsetType.Absolute; + + final double _value; + final _DashOffsetType _dashOffsetType; + + double _calculate(double length) => + _dashOffsetType == _DashOffsetType.Absolute ? _value : length * _value; +} diff --git a/lib/getwidget.dart b/lib/getwidget.dart index a2c1405a..651ec4e4 100644 --- a/lib/getwidget.dart +++ b/lib/getwidget.dart @@ -8,6 +8,7 @@ export 'package:getwidget/components/avatar/gf_avatar.dart'; export 'package:getwidget/components/badge/gf_badge.dart'; export 'package:getwidget/components/badge/gf_button_badge.dart'; export 'package:getwidget/components/badge/gf_icon_badge.dart'; +export 'package:getwidget/components/border/gf_border.dart'; export 'package:getwidget/components/bottom_sheet/gf_bottom_sheet.dart'; export 'package:getwidget/components/button/gf_button.dart'; export 'package:getwidget/components/button/gf_button_bar.dart'; @@ -39,6 +40,8 @@ export 'package:getwidget/components/toast/gf_toast.dart'; export 'package:getwidget/components/toggle/gf_toggle.dart'; export 'package:getwidget/components/typography/gf_typography.dart'; + + export 'colors/gf_color.dart'; export 'direction/gf_shimmer_direction.dart'; export 'position/gf_position.dart'; @@ -48,6 +51,7 @@ export 'shape/gf_button_shape.dart'; export 'shape/gf_icon_button_shape.dart'; export 'size/gf_size.dart'; export 'types/gf_alert_type.dart'; +export 'types/gf_border_type.dart'; export 'types/gf_button_type.dart'; export 'types/gf_checkbox_type.dart'; export 'types/gf_loader_type.dart'; diff --git a/lib/types/gf_border_type.dart b/lib/types/gf_border_type.dart new file mode 100644 index 00000000..bea0b2a9 --- /dev/null +++ b/lib/types/gf_border_type.dart @@ -0,0 +1 @@ +enum GFBorderType { Circle, RRect, Rect, Oval } diff --git a/pubspec.lock b/pubspec.lock index 3485d141..e69de29b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,146 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.5.0-nullsafety" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety.2" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.15.0-nullsafety.2" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.10-nullsafety" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0-nullsafety.2" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0-nullsafety" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0-nullsafety" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0-nullsafety" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.19-nullsafety" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0-nullsafety.2" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.2" -sdks: - dart: ">=2.10.0-0.0.dev <2.10.0"