[0.1.0]
This commit is contained in:
@@ -48,8 +48,8 @@ class GradientBoxBorder extends Border {
|
||||
}
|
||||
|
||||
void _paintCircle(Canvas canvas, Rect rect) {
|
||||
final paint = _getPaint(rect);
|
||||
final radius = (rect.shortestSide - width) / 2.0;
|
||||
final Paint paint = _getPaint(rect);
|
||||
final double radius = (rect.shortestSide - width) / 2.0;
|
||||
canvas.drawCircle(rect.center, radius, paint);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,17 +55,17 @@ class GradientOutlineInputBorder extends InputBorder {
|
||||
double gapPercentage = 0.0,
|
||||
TextDirection? textDirection,
|
||||
}) {
|
||||
final paint = _getPaint(rect);
|
||||
final outer = borderRadius.toRRect(rect);
|
||||
final center = outer.deflate(borderSide.width / 2.0);
|
||||
final Paint paint = _getPaint(rect);
|
||||
final RRect outer = borderRadius.toRRect(rect);
|
||||
final RRect center = outer.deflate(borderSide.width / 2.0);
|
||||
if (gapStart == null || gapExtent <= 0.0 || gapPercentage == 0.0) {
|
||||
canvas.drawRRect(center, paint);
|
||||
} else {
|
||||
final extent =
|
||||
final double extent =
|
||||
lerpDouble(0.0, gapExtent + gapPadding * 2.0, gapPercentage)!;
|
||||
switch (textDirection!) {
|
||||
case TextDirection.rtl:
|
||||
final path = _gapBorderPath(
|
||||
final Path path = _gapBorderPath(
|
||||
canvas,
|
||||
center,
|
||||
math.max(0, gapStart + gapPadding - extent),
|
||||
@@ -75,7 +75,7 @@ class GradientOutlineInputBorder extends InputBorder {
|
||||
break;
|
||||
|
||||
case TextDirection.ltr:
|
||||
final path = _gapBorderPath(
|
||||
final Path path = _gapBorderPath(
|
||||
canvas,
|
||||
center,
|
||||
math.max(0, gapStart - gapPadding),
|
||||
@@ -112,39 +112,39 @@ class GradientOutlineInputBorder extends InputBorder {
|
||||
// When the corner radii on any side add up to be greater than the
|
||||
// given height, each radius has to be scaled to not exceed the
|
||||
// size of the width/height of the RRect.
|
||||
final scaledRRect = center.scaleRadii();
|
||||
final RRect scaledRRect = center.scaleRadii();
|
||||
|
||||
final tlCorner = Rect.fromLTWH(
|
||||
final Rect tlCorner = Rect.fromLTWH(
|
||||
scaledRRect.left,
|
||||
scaledRRect.top,
|
||||
scaledRRect.tlRadiusX * 2.0,
|
||||
scaledRRect.tlRadiusY * 2.0,
|
||||
);
|
||||
final trCorner = Rect.fromLTWH(
|
||||
final Rect trCorner = Rect.fromLTWH(
|
||||
scaledRRect.right - scaledRRect.trRadiusX * 2.0,
|
||||
scaledRRect.top,
|
||||
scaledRRect.trRadiusX * 2.0,
|
||||
scaledRRect.trRadiusY * 2.0,
|
||||
);
|
||||
final brCorner = Rect.fromLTWH(
|
||||
final Rect brCorner = Rect.fromLTWH(
|
||||
scaledRRect.right - scaledRRect.brRadiusX * 2.0,
|
||||
scaledRRect.bottom - scaledRRect.brRadiusY * 2.0,
|
||||
scaledRRect.brRadiusX * 2.0,
|
||||
scaledRRect.brRadiusY * 2.0,
|
||||
);
|
||||
final blCorner = Rect.fromLTWH(
|
||||
final Rect blCorner = Rect.fromLTWH(
|
||||
scaledRRect.left,
|
||||
scaledRRect.bottom - scaledRRect.blRadiusY * 2.0,
|
||||
scaledRRect.blRadiusX * 2.0,
|
||||
scaledRRect.blRadiusX * 2.0,
|
||||
);
|
||||
|
||||
const cornerArcSweep = math.pi / 2.0;
|
||||
final tlCornerArcSweep = start < scaledRRect.tlRadiusX
|
||||
const double cornerArcSweep = math.pi / 2.0;
|
||||
final double tlCornerArcSweep = start < scaledRRect.tlRadiusX
|
||||
? math.asin((start / scaledRRect.tlRadiusX).clamp(-1.0, 1.0))
|
||||
: math.pi / 2.0;
|
||||
|
||||
final path = Path()
|
||||
final Path path = Path()
|
||||
..addArc(tlCorner, math.pi, tlCornerArcSweep)
|
||||
..moveTo(scaledRRect.left + scaledRRect.tlRadiusX, scaledRRect.top);
|
||||
|
||||
@@ -152,16 +152,16 @@ class GradientOutlineInputBorder extends InputBorder {
|
||||
path.lineTo(scaledRRect.left + start, scaledRRect.top);
|
||||
}
|
||||
|
||||
const trCornerArcStart = (3 * math.pi) / 2.0;
|
||||
const trCornerArcSweep = cornerArcSweep;
|
||||
const double trCornerArcStart = (3 * math.pi) / 2.0;
|
||||
const double trCornerArcSweep = cornerArcSweep;
|
||||
if (start + extent < scaledRRect.width - scaledRRect.trRadiusX) {
|
||||
path
|
||||
..relativeMoveTo(extent, 0)
|
||||
..lineTo(scaledRRect.right - scaledRRect.trRadiusX, scaledRRect.top)
|
||||
..addArc(trCorner, trCornerArcStart, trCornerArcSweep);
|
||||
} else if (start + extent < scaledRRect.width) {
|
||||
final dx = scaledRRect.width - (start + extent);
|
||||
final sweep = math.acos(dx / scaledRRect.trRadiusX);
|
||||
final double dx = scaledRRect.width - (start + extent);
|
||||
final double sweep = math.acos(dx / scaledRRect.trRadiusX);
|
||||
path.addArc(trCorner, trCornerArcStart + sweep, trCornerArcSweep - sweep);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GradientUnderlineInputBorder extends InputBorder {
|
||||
@@ -52,7 +49,7 @@ class GradientUnderlineInputBorder extends InputBorder {
|
||||
double gapPercentage = 0.0,
|
||||
TextDirection? textDirection,
|
||||
}) {
|
||||
final paint = _getPaint(rect);
|
||||
final Paint paint = _getPaint(rect);
|
||||
Rect underlineRect = Rect.fromLTWH(rect.left, rect.height - width, rect.width, width);
|
||||
canvas.drawRect(underlineRect, paint);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ class AstromicButtons {
|
||||
onTap: onTap,
|
||||
onHold: onHold,
|
||||
configuration: configuration,
|
||||
isUnderlined: isUnderlined ?? (e) => e,
|
||||
isUnderlined: isUnderlined ?? (bool e) => e,
|
||||
contentPadding: contentPadding,
|
||||
style: style,
|
||||
text: text,
|
||||
|
||||
@@ -12,16 +12,6 @@ import 'models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicButtonBase extends StatefulWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onHold;
|
||||
//s1 -- Configurations
|
||||
final AstromicButtonConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted)? style;
|
||||
//s1 -- Content
|
||||
final Widget Function(bool isEnabled, bool isHighlighted) child;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicButtonBase({
|
||||
@@ -38,6 +28,16 @@ class AstromicButtonBase extends StatefulWidget {
|
||||
}) : super(
|
||||
key: key,
|
||||
);
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onHold;
|
||||
//s1 -- Configurations
|
||||
final AstromicButtonConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted)? style;
|
||||
//s1 -- Content
|
||||
final Widget Function(bool isEnabled, bool isHighlighted) child;
|
||||
|
||||
@override
|
||||
State<AstromicButtonBase> createState() => _AstromicButtonBaseState();
|
||||
@@ -121,7 +121,7 @@ class _AstromicButtonBaseState extends State<AstromicButtonBase> {
|
||||
onTap: _config.isEnabled && widget.onTap != null ? widget.onTap : null,
|
||||
onLongPress: _config.isEnabled && widget.onHold != null ? widget.onHold : null,
|
||||
onHighlightChanged: _config.withHighlightChange
|
||||
? (v) {
|
||||
? (bool v) {
|
||||
setState(() {
|
||||
_isHighlighted = v;
|
||||
});
|
||||
|
||||
@@ -12,18 +12,6 @@ import 'models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicIconButton extends StatefulWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final void Function(VoidCallback start, VoidCallback stop)? onTap;
|
||||
final Function(VoidCallback start, VoidCallback stop)? onHold;
|
||||
//s1 -- Configurations
|
||||
final AstromicButtonConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final bool isCircular;
|
||||
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted, bool isLoading)? style;
|
||||
//s1 -- Content
|
||||
final Widget? loadingContent;
|
||||
final Widget Function(bool isEnabled, bool isHighlighted) icon;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicIconButton({
|
||||
@@ -40,6 +28,18 @@ class AstromicIconButton extends StatefulWidget {
|
||||
this.loadingContent,
|
||||
required this.icon,
|
||||
});
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final void Function(VoidCallback start, VoidCallback stop)? onTap;
|
||||
final Function(VoidCallback start, VoidCallback stop)? onHold;
|
||||
//s1 -- Configurations
|
||||
final AstromicButtonConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final bool isCircular;
|
||||
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted, bool isLoading)? style;
|
||||
//s1 -- Content
|
||||
final Widget? loadingContent;
|
||||
final Widget Function(bool isEnabled, bool isHighlighted) icon;
|
||||
|
||||
@override
|
||||
State<AstromicIconButton> createState() => _AstromicIconButtonState();
|
||||
@@ -117,10 +117,10 @@ class _AstromicIconButtonState extends State<AstromicIconButton> {
|
||||
: null,
|
||||
style: widget.style == null
|
||||
? null
|
||||
: (enabled, highlighted) => widget.style!.call(enabled, highlighted, isLoading).copyWith(
|
||||
: (bool enabled, bool highlighted) => widget.style!.call(enabled, highlighted, isLoading).copyWith(
|
||||
borderRadius: widget.isCircular ? BorderRadiusDirectional.circular(100000000000) : null,
|
||||
),
|
||||
child: (enabled, highlighted) => isLoading && widget.loadingContent != null ? widget.loadingContent! : widget.icon(enabled, highlighted),
|
||||
child: (bool enabled, bool highlighted) => isLoading && widget.loadingContent != null ? widget.loadingContent! : widget.icon(enabled, highlighted),
|
||||
);
|
||||
|
||||
//s1 -Widgets
|
||||
|
||||
@@ -12,22 +12,6 @@ import 'models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicLinkButton extends StatelessWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onHold;
|
||||
//s1 -- Configurations
|
||||
final AstromicButtonConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final bool Function(bool isEnabled) isUnderlined;
|
||||
final EdgeInsetsGeometry? contentPadding;
|
||||
final TextStyle Function(bool isEnabled)? style;
|
||||
//
|
||||
//s1 -- Content
|
||||
final String? text;
|
||||
final Widget? textWidget;
|
||||
final Widget? prefix;
|
||||
final Widget? suffix;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicLinkButton({
|
||||
@@ -50,6 +34,22 @@ class AstromicLinkButton extends StatelessWidget {
|
||||
super(
|
||||
key: key,
|
||||
);
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onHold;
|
||||
//s1 -- Configurations
|
||||
final AstromicButtonConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final bool Function(bool isEnabled) isUnderlined;
|
||||
final EdgeInsetsGeometry? contentPadding;
|
||||
final TextStyle Function(bool isEnabled)? style;
|
||||
//
|
||||
//s1 -- Content
|
||||
final String? text;
|
||||
final Widget? textWidget;
|
||||
final Widget? prefix;
|
||||
final Widget? suffix;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -64,27 +64,24 @@ class AstromicLinkButton extends StatelessWidget {
|
||||
//SECTION - Build Return
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
textDirection: configuration?.textDirection,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
AstromicButtonBase(
|
||||
onTap: onTap,
|
||||
onHold: onHold,
|
||||
//
|
||||
configuration: configuration,
|
||||
//
|
||||
style: (isEnabled, isHighlighted) => AstromicButtonStyle(
|
||||
style: (bool isEnabled, bool isHighlighted) => AstromicButtonStyle(
|
||||
contentPadding: contentPadding,
|
||||
borderWidth: 0,
|
||||
borderRadius: BorderRadius.zero,
|
||||
borderColor: Colors.transparent,
|
||||
),
|
||||
//
|
||||
child: (isEnabled, isHighlighted) => Row(
|
||||
child: (bool isEnabled, bool isHighlighted) => Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
if (prefix != null) prefix!,
|
||||
textWidget != null
|
||||
? textWidget!
|
||||
|
||||
@@ -2,23 +2,6 @@ import 'package:flutter/material.dart';
|
||||
|
||||
/// Styling model for the button element.
|
||||
class AstromicButtonStyle {
|
||||
//s1 -- Colors
|
||||
final Color? backgroundColor;
|
||||
final Gradient? backgroundGradient;
|
||||
final Color? hoverColor;
|
||||
final Color? splashColor;
|
||||
final Color? highlightColor;
|
||||
final Color? borderColor;
|
||||
final Gradient? borderGradient;
|
||||
//
|
||||
//s1 -- Spacing & Insets
|
||||
final double? fixedHeight;
|
||||
final double? fixedWidth;
|
||||
final EdgeInsetsGeometry? contentPadding;
|
||||
final BorderRadiusGeometry? borderRadius;
|
||||
final double? borderWidth;
|
||||
//s1 -- Interactions
|
||||
final InteractiveInkFeatureFactory? splashFactory;
|
||||
const AstromicButtonStyle({
|
||||
this.backgroundColor = Colors.transparent,
|
||||
this.backgroundGradient,
|
||||
@@ -37,6 +20,23 @@ class AstromicButtonStyle {
|
||||
this.splashFactory,
|
||||
//
|
||||
});
|
||||
//s1 -- Colors
|
||||
final Color? backgroundColor;
|
||||
final Gradient? backgroundGradient;
|
||||
final Color? hoverColor;
|
||||
final Color? splashColor;
|
||||
final Color? highlightColor;
|
||||
final Color? borderColor;
|
||||
final Gradient? borderGradient;
|
||||
//
|
||||
//s1 -- Spacing & Insets
|
||||
final double? fixedHeight;
|
||||
final double? fixedWidth;
|
||||
final EdgeInsetsGeometry? contentPadding;
|
||||
final BorderRadiusGeometry? borderRadius;
|
||||
final double? borderWidth;
|
||||
//s1 -- Interactions
|
||||
final InteractiveInkFeatureFactory? splashFactory;
|
||||
|
||||
AstromicButtonStyle copyWith({
|
||||
Color? backgroundColor,
|
||||
|
||||
@@ -13,20 +13,6 @@ import 'models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicStateButton extends StatefulWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final void Function(VoidCallback start, VoidCallback stop)? onTap;
|
||||
final Function(VoidCallback start, VoidCallback stop)? onHold;
|
||||
//s1 -- Configurations
|
||||
final AstromicButtonConfiguration? configuration;
|
||||
|
||||
//s1 -- Style
|
||||
final AstromicSizingStrategy? widthSizingStrategy;
|
||||
final AstromicSizingStrategy? heightSizingStrategy;
|
||||
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted, bool isLoading)? style;
|
||||
//s1 -- Content
|
||||
final Widget? loadingContent;
|
||||
final Widget Function(bool isEnabled, bool isHighlighted) content;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicStateButton({
|
||||
@@ -44,6 +30,20 @@ class AstromicStateButton extends StatefulWidget {
|
||||
this.loadingContent,
|
||||
required this.content,
|
||||
}) : assert(heightSizingStrategy != AstromicSizingStrategy.fill, 'Height strategy cannot be fill');
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final void Function(VoidCallback start, VoidCallback stop)? onTap;
|
||||
final Function(VoidCallback start, VoidCallback stop)? onHold;
|
||||
//s1 -- Configurations
|
||||
final AstromicButtonConfiguration? configuration;
|
||||
|
||||
//s1 -- Style
|
||||
final AstromicSizingStrategy? widthSizingStrategy;
|
||||
final AstromicSizingStrategy? heightSizingStrategy;
|
||||
final AstromicButtonStyle Function(bool isEnabled, bool isHighlighted, bool isLoading)? style;
|
||||
//s1 -- Content
|
||||
final Widget? loadingContent;
|
||||
final Widget Function(bool isEnabled, bool isHighlighted) content;
|
||||
|
||||
@override
|
||||
State<AstromicStateButton> createState() => _AstromicStateButtonState();
|
||||
@@ -119,22 +119,20 @@ class _AstromicStateButtonState extends State<AstromicStateButton> {
|
||||
});
|
||||
}
|
||||
: null,
|
||||
style: (enabled, highlighted) => widget.style!(enabled, highlighted, isLoading).copyWith(
|
||||
style: (bool enabled, bool highlighted) => widget.style!(enabled, highlighted, isLoading).copyWith(
|
||||
contentPadding: widget.heightSizingStrategy == AstromicSizingStrategy.fixed && widget.widthSizingStrategy == AstromicSizingStrategy.fixed
|
||||
? EdgeInsets.zero
|
||||
: widget.heightSizingStrategy == AstromicSizingStrategy.fixed && widget.widthSizingStrategy != AstromicSizingStrategy.fixed
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: widget.style!(enabled, highlighted, isLoading).contentPadding?.horizontal ?? 0,
|
||||
vertical: 0,
|
||||
)
|
||||
: widget.widthSizingStrategy == AstromicSizingStrategy.fixed && widget.heightSizingStrategy != AstromicSizingStrategy.fixed
|
||||
? EdgeInsets.symmetric(
|
||||
vertical: widget.style!(enabled, highlighted, isLoading).contentPadding?.vertical ?? 0,
|
||||
horizontal: 0,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
child: (enabled, highlighted) => isLoading && widget.loadingContent != null ? widget.loadingContent! : widget.content(enabled, highlighted),
|
||||
child: (bool enabled, bool highlighted) => isLoading && widget.loadingContent != null ? widget.loadingContent! : widget.content(enabled, highlighted),
|
||||
);
|
||||
|
||||
//s1 -Widgets
|
||||
@@ -143,7 +141,7 @@ class _AstromicStateButtonState extends State<AstromicStateButton> {
|
||||
//SECTION - Build Return
|
||||
return Row(
|
||||
mainAxisSize: widget.widthSizingStrategy == AstromicSizingStrategy.hug ? MainAxisSize.min : MainAxisSize.max,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
widget.widthSizingStrategy == AstromicSizingStrategy.fill
|
||||
? Expanded(
|
||||
child: SizedBox(
|
||||
|
||||
@@ -30,7 +30,7 @@ class AstromicFields {
|
||||
Iterable<ContextMenuButtonItem>? contextButtons,
|
||||
}) =>
|
||||
Column(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
AstromicTextField(
|
||||
textController: controller,
|
||||
stateKey: stateKey,
|
||||
@@ -64,8 +64,8 @@ class AstromicFields {
|
||||
Widget? Function(bool isEnabled, VoidCallback stateSetter)? suffixWidget,
|
||||
Widget? Function(bool isEnabled)? messageBuilder}) =>
|
||||
Column(
|
||||
children: [
|
||||
AstromicActionField(
|
||||
children: <Widget>[
|
||||
AstromicActionField<T>(
|
||||
stateKey: stateKey,
|
||||
textController: controller,
|
||||
initialValue: initialValue,
|
||||
|
||||
@@ -12,6 +12,26 @@ import 'models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicActionField<T> extends StatefulWidget {
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicActionField({
|
||||
super.key,
|
||||
//
|
||||
this.initialValue,
|
||||
this.stateKey,
|
||||
required this.textController,
|
||||
required this.onValueChangedMapper,
|
||||
this.onTap,
|
||||
this.onHold,
|
||||
//
|
||||
this.configuration,
|
||||
this.style,
|
||||
//
|
||||
this.hint,
|
||||
this.prefixWidget,
|
||||
this.suffixWidget,
|
||||
this.messageBuilder,
|
||||
});
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final Key? stateKey;
|
||||
@@ -33,26 +53,6 @@ class AstromicActionField<T> extends StatefulWidget {
|
||||
final Widget? Function(bool isEnabled, VoidCallback stateSetter)? prefixWidget;
|
||||
final Widget? Function(bool isEnabled, VoidCallback stateSetter)? suffixWidget;
|
||||
final Widget? Function(bool isEnabled)? messageBuilder;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicActionField({
|
||||
super.key,
|
||||
//
|
||||
this.initialValue,
|
||||
this.stateKey,
|
||||
required this.textController,
|
||||
required this.onValueChangedMapper,
|
||||
this.onTap,
|
||||
this.onHold,
|
||||
//
|
||||
this.configuration,
|
||||
this.style,
|
||||
//
|
||||
this.hint,
|
||||
this.prefixWidget,
|
||||
this.suffixWidget,
|
||||
this.messageBuilder,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AstromicActionField<T>> createState() => _AstromicActionFieldState<T>();
|
||||
@@ -136,12 +136,12 @@ class _AstromicActionFieldState<T> extends State<AstromicActionField<T>> {
|
||||
// onChanged: (v) {},
|
||||
// onSubmited: (v) {},
|
||||
configuration: widget.configuration,
|
||||
style: widget.style == null ? null : (enabled, focused) => widget.style!(enabled),
|
||||
style: widget.style == null ? null : (bool enabled, bool focused) => widget.style!(enabled),
|
||||
hint: widget.hint,
|
||||
prefixWidget: widget.prefixWidget == null ? null : (enabled, focused, stateSetter) => widget.prefixWidget!(enabled, stateSetter),
|
||||
suffixWidget: widget.suffixWidget == null ? null : (enabled, focused, stateSetter) => widget.suffixWidget!(enabled, stateSetter),
|
||||
messageBuilder: widget.messageBuilder == null ? null : (enabled, focused) => widget.messageBuilder!(enabled),
|
||||
fieldStackedWidget: (finalHeight, border) => SizedBox(
|
||||
prefixWidget: widget.prefixWidget == null ? null : (bool enabled, bool focused, void Function() stateSetter) => widget.prefixWidget!(enabled, stateSetter),
|
||||
suffixWidget: widget.suffixWidget == null ? null : (bool enabled, bool focused, void Function() stateSetter) => widget.suffixWidget!(enabled, stateSetter),
|
||||
messageBuilder: widget.messageBuilder == null ? null : (bool enabled, bool focused) => widget.messageBuilder!(enabled),
|
||||
fieldStackedWidget: (double finalHeight, ShapeBorder? border) => SizedBox(
|
||||
width: double.infinity,
|
||||
height: finalHeight,
|
||||
child: Material(
|
||||
|
||||
@@ -17,6 +17,27 @@ import 'models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicFieldBase extends StatefulWidget {
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicFieldBase({
|
||||
super.key,
|
||||
//
|
||||
required this.textController,
|
||||
this.stateKey,
|
||||
this.onChanged,
|
||||
this.onSubmited,
|
||||
//
|
||||
this.configuration,
|
||||
//
|
||||
this.style,
|
||||
//
|
||||
this.fieldStackedWidget,
|
||||
this.hint,
|
||||
this.prefixWidget,
|
||||
this.suffixWidget,
|
||||
this.messageBuilder,
|
||||
this.contextButtons,
|
||||
});
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final TextEditingController textController;
|
||||
@@ -40,27 +61,6 @@ class AstromicFieldBase extends StatefulWidget {
|
||||
final Widget? Function(bool isEnabled, bool isFocused)? messageBuilder;
|
||||
//
|
||||
final Iterable<ContextMenuButtonItem>? contextButtons;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicFieldBase({
|
||||
super.key,
|
||||
//
|
||||
required this.textController,
|
||||
this.stateKey,
|
||||
this.onChanged,
|
||||
this.onSubmited,
|
||||
//
|
||||
this.configuration,
|
||||
//
|
||||
this.style,
|
||||
//
|
||||
this.fieldStackedWidget,
|
||||
this.hint,
|
||||
this.prefixWidget,
|
||||
this.suffixWidget,
|
||||
this.messageBuilder,
|
||||
this.contextButtons,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AstromicFieldBase> createState() => _AstromicFieldBaseState();
|
||||
@@ -128,9 +128,9 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
|
||||
//SECTION - Stateless functions
|
||||
_getTextHeight(String text, TextStyle style, ui.TextDirection direction) {
|
||||
final span = TextSpan(text: text, style: style);
|
||||
final tp = TextPainter(text: span, textDirection: direction);
|
||||
tp.layout(maxWidth: double.infinity);
|
||||
final TextSpan span = TextSpan(text: text, style: style);
|
||||
final TextPainter tp = TextPainter(text: span, textDirection: direction);
|
||||
tp.layout();
|
||||
return tp.height;
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
? widget.textController.text
|
||||
: (widget.hint?.isNotEmpty ?? false)
|
||||
? widget.hint!
|
||||
: "",
|
||||
: '',
|
||||
widget.textController.text.isNotEmpty && _style().textStyle != null
|
||||
? _style().textStyle!
|
||||
: _style().hintStyle != null
|
||||
@@ -213,7 +213,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
) ??
|
||||
BorderRadius.circular(0))
|
||||
: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: style.borderColor ?? Colors.grey, width: style.borderWidth ?? 2.0, style: BorderStyle.solid),
|
||||
borderSide: BorderSide(color: style.borderColor ?? Colors.grey, width: style.borderWidth ?? 2.0),
|
||||
borderRadius: style.borderRadius?.resolve(
|
||||
_config.textDirection,
|
||||
) ??
|
||||
@@ -229,7 +229,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
) ??
|
||||
BorderRadius.circular(0))
|
||||
: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: style.borderColor ?? Colors.grey, width: style.borderWidth ?? 2.0, style: BorderStyle.solid),
|
||||
borderSide: BorderSide(color: style.borderColor ?? Colors.grey, width: style.borderWidth ?? 2.0),
|
||||
borderRadius: style.borderRadius?.resolve(
|
||||
_config.textDirection,
|
||||
) ??
|
||||
@@ -334,7 +334,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Directionality(
|
||||
textDirection: _finalTextDirection(),
|
||||
child: Container(
|
||||
@@ -345,7 +345,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
: null,
|
||||
alignment: _style().textAlignVertical.toAlignment(),
|
||||
child: Stack(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
TextFormField(
|
||||
//s1 -- Functionality
|
||||
key: widget.stateKey,
|
||||
@@ -353,7 +353,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
focusNode: _focusNode,
|
||||
textInputAction: _config.inputAction,
|
||||
//
|
||||
onChanged: (v) {
|
||||
onChanged: (String v) {
|
||||
setState(() {
|
||||
if (widget.onChanged != null) {
|
||||
widget.onChanged!(v);
|
||||
@@ -361,7 +361,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
});
|
||||
},
|
||||
//
|
||||
onFieldSubmitted: (v) {
|
||||
onFieldSubmitted: (String v) {
|
||||
//
|
||||
if (_config.inputAction == TextInputAction.next) {
|
||||
_focusNode.nextFocus();
|
||||
@@ -371,7 +371,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
}
|
||||
},
|
||||
//
|
||||
onTapOutside: (tapEvent) {
|
||||
onTapOutside: (PointerDownEvent tapEvent) {
|
||||
if (_config.unfocusOnTapOutside) {
|
||||
_focusNode.unfocus();
|
||||
}
|
||||
@@ -398,7 +398,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
//
|
||||
expands: _config.isFixedHeight && _config.isTextArea ? true : false,
|
||||
// - Validation
|
||||
validator: _config.validator != null ? (s) => _config.validator!(_config.isEnabled, _isFocused, s) : null,
|
||||
validator: _config.validator != null ? (String? s) => _config.validator!(_config.isEnabled, _isFocused, s) : null,
|
||||
// - Validation
|
||||
//s1 -- Style
|
||||
style: _style().textStyle,
|
||||
@@ -409,7 +409,7 @@ class _AstromicFieldBaseState extends State<AstromicFieldBase> {
|
||||
//s1 -- Input Decoration
|
||||
decoration: inputDecoration,
|
||||
//s1 -- Content
|
||||
contextMenuBuilder: (_, state) {
|
||||
contextMenuBuilder: (_, EditableTextState state) {
|
||||
List<ContextMenuButtonItem> baseContextButtons = state.contextMenuButtonItems;
|
||||
if (widget.contextButtons != null) {
|
||||
baseContextButtons.addAll(widget.contextButtons!);
|
||||
|
||||
@@ -1,34 +1,9 @@
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/// Configuration model for the field element.
|
||||
class AstromicFieldConfiguration {
|
||||
//
|
||||
final bool isEnabled;
|
||||
final bool? isTextObscured;
|
||||
final bool isFixedHeight;
|
||||
final bool isTextArea;
|
||||
//
|
||||
final bool withAutofocus;
|
||||
final bool respectBorderWidthPadding;
|
||||
final bool withObscurity;
|
||||
final bool withAutomaticDirectionalitySwitching;
|
||||
final bool unfocusOnTapOutside;
|
||||
//
|
||||
final ui.TextDirection? hintDirection;
|
||||
final ui.TextDirection? textDirection;
|
||||
final ui.TextDirection? messageDirection;
|
||||
//
|
||||
final TextInputType inputType;
|
||||
final TextInputAction inputAction;
|
||||
//
|
||||
final MaxLengthEnforcement maxLengthEnforcement;
|
||||
//
|
||||
final AutovalidateMode? validatingMode;
|
||||
final String? Function(bool isEnabled, bool isFocused, String? text)? validator;
|
||||
final List<TextInputFormatter>? inputFormatters;
|
||||
//
|
||||
const AstromicFieldConfiguration({
|
||||
this.isEnabled = true,
|
||||
@@ -55,6 +30,30 @@ class AstromicFieldConfiguration {
|
||||
//
|
||||
});
|
||||
//
|
||||
final bool isEnabled;
|
||||
final bool? isTextObscured;
|
||||
final bool isFixedHeight;
|
||||
final bool isTextArea;
|
||||
//
|
||||
final bool withAutofocus;
|
||||
final bool respectBorderWidthPadding;
|
||||
final bool withObscurity;
|
||||
final bool withAutomaticDirectionalitySwitching;
|
||||
final bool unfocusOnTapOutside;
|
||||
//
|
||||
final ui.TextDirection? hintDirection;
|
||||
final ui.TextDirection? textDirection;
|
||||
final ui.TextDirection? messageDirection;
|
||||
//
|
||||
final TextInputType inputType;
|
||||
final TextInputAction inputAction;
|
||||
//
|
||||
final MaxLengthEnforcement maxLengthEnforcement;
|
||||
//
|
||||
final AutovalidateMode? validatingMode;
|
||||
final String? Function(bool isEnabled, bool isFocused, String? text)? validator;
|
||||
final List<TextInputFormatter>? inputFormatters;
|
||||
//
|
||||
|
||||
AstromicFieldConfiguration copyWith({
|
||||
bool? isEnabled,
|
||||
|
||||
@@ -3,6 +3,37 @@ import '../enums/border_type.enum.dart';
|
||||
|
||||
/// Styling model for the field element.
|
||||
class AstromicFieldStyle {
|
||||
|
||||
const AstromicFieldStyle({
|
||||
this.isFilled = true,
|
||||
//
|
||||
this.minLines = 1,
|
||||
this.maxLines = 1,
|
||||
this.maxLength,
|
||||
this.textAlign = TextAlign.start,
|
||||
this.textAlignVertical = TextAlignVertical.center,
|
||||
//
|
||||
this.fixedHeight,
|
||||
//
|
||||
this.borderRadius,
|
||||
this.borderWidth,
|
||||
this.borderType = AstromicFieldBorderType.underlined,
|
||||
this.customBorder,
|
||||
//
|
||||
this.contentPadding = EdgeInsets.zero,
|
||||
this.messagePadding = EdgeInsets.zero,
|
||||
this.prefixSpacing = 4,
|
||||
this.prefixSize = 24,
|
||||
this.suffixSpacing = 4,
|
||||
this.suffixSize = 24,
|
||||
//
|
||||
this.fillColor = const Color(0xffffffff),
|
||||
this.borderColor,
|
||||
this.borderGradient,
|
||||
this.cursorColor,
|
||||
this.hintStyle,
|
||||
this.textStyle,
|
||||
});
|
||||
//s1 - Styling Configs
|
||||
final bool isFilled;
|
||||
//s1 - Sizing & Spacing
|
||||
@@ -38,37 +69,6 @@ class AstromicFieldStyle {
|
||||
//s1 - Styling
|
||||
final TextStyle? hintStyle;
|
||||
final TextStyle? textStyle;
|
||||
|
||||
const AstromicFieldStyle({
|
||||
this.isFilled = true,
|
||||
//
|
||||
this.minLines = 1,
|
||||
this.maxLines = 1,
|
||||
this.maxLength,
|
||||
this.textAlign = TextAlign.start,
|
||||
this.textAlignVertical = TextAlignVertical.center,
|
||||
//
|
||||
this.fixedHeight,
|
||||
//
|
||||
this.borderRadius,
|
||||
this.borderWidth,
|
||||
this.borderType = AstromicFieldBorderType.underlined,
|
||||
this.customBorder,
|
||||
//
|
||||
this.contentPadding = EdgeInsets.zero,
|
||||
this.messagePadding = EdgeInsets.zero,
|
||||
this.prefixSpacing = 4,
|
||||
this.prefixSize = 24,
|
||||
this.suffixSpacing = 4,
|
||||
this.suffixSize = 24,
|
||||
//
|
||||
this.fillColor = const Color(0xffffffff),
|
||||
this.borderColor,
|
||||
this.borderGradient,
|
||||
this.cursorColor,
|
||||
this.hintStyle,
|
||||
this.textStyle,
|
||||
});
|
||||
//
|
||||
AstromicFieldStyle copyWith({
|
||||
bool? isFilled,
|
||||
|
||||
@@ -12,6 +12,26 @@ import 'models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicTextField extends StatelessWidget {
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicTextField({
|
||||
super.key,
|
||||
//
|
||||
required this.textController,
|
||||
this.stateKey,
|
||||
this.onChanged,
|
||||
this.onSubmited,
|
||||
//
|
||||
this.configuration,
|
||||
//
|
||||
this.style,
|
||||
//
|
||||
this.hint,
|
||||
this.prefixWidget,
|
||||
this.suffixWidget,
|
||||
this.messageBuilder,
|
||||
this.contextButtons,
|
||||
});
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final TextEditingController textController;
|
||||
@@ -34,26 +54,6 @@ class AstromicTextField extends StatelessWidget {
|
||||
final Widget? Function(bool isEnabled, bool isFocused)? messageBuilder;
|
||||
//
|
||||
final Iterable<ContextMenuButtonItem>? contextButtons;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicTextField({
|
||||
super.key,
|
||||
//
|
||||
required this.textController,
|
||||
this.stateKey,
|
||||
this.onChanged,
|
||||
this.onSubmited,
|
||||
//
|
||||
this.configuration,
|
||||
//
|
||||
this.style,
|
||||
//
|
||||
this.hint,
|
||||
this.prefixWidget,
|
||||
this.suffixWidget,
|
||||
this.messageBuilder,
|
||||
this.contextButtons,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@@ -45,7 +45,7 @@ class AstromicSelectors {
|
||||
required Widget Function(T item, bool isEnabled, bool isSelected, VoidCallback? onTap, VoidCallback? onClearTapped) itemBuilder,
|
||||
Widget Function(List<Widget> items)? groupBuilder,
|
||||
}) =>
|
||||
AstromicChipSelector(
|
||||
AstromicChipSelector<T>(
|
||||
initialSelectedValues: initialSelectedValues,
|
||||
onChanged: onChanged,
|
||||
configuration: configuration,
|
||||
@@ -53,6 +53,6 @@ class AstromicSelectors {
|
||||
runSpacing: runSpacing,
|
||||
items: items,
|
||||
itemBuilder: itemBuilder,
|
||||
groupBuilder: groupBuilder!,
|
||||
groupBuilder: groupBuilder,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,20 +13,6 @@ import 'models/models.exports.dart';
|
||||
|
||||
/// Selector that allows multible items to be selected from a group of items with the option to unselect and clear.
|
||||
class AstromicChipSelector<T> extends StatefulWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final List<T>? initialSelectedValues;
|
||||
final Function(List<T> selectedItems)? onChanged;
|
||||
//s1 -- Configuration
|
||||
final AstromicChipSelectorConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final double? itemSpacing;
|
||||
final double? runSpacing;
|
||||
//
|
||||
//s1 -- Content
|
||||
final List<(T item, bool isEnabled)> items;
|
||||
final Widget Function(T item, bool isEnabled, bool isSelected, VoidCallback? onTap, VoidCallback? onClearTapped) itemBuilder;
|
||||
final Widget Function(List<Widget> items)? groupBuilder;
|
||||
//!SECTION
|
||||
//
|
||||
AstromicChipSelector({
|
||||
@@ -44,12 +30,26 @@ class AstromicChipSelector<T> extends StatefulWidget {
|
||||
required this.itemBuilder,
|
||||
this.groupBuilder,
|
||||
}) : assert(
|
||||
(configuration?.isNullable ?? true) || (initialSelectedValues != null && items.map((i) => i.$1).toList().containsAll(initialSelectedValues)),
|
||||
"Initial values are not all present in the items!",
|
||||
(configuration?.isNullable ?? true) || (initialSelectedValues != null && items.map(((T, bool) i) => i.$1).toList().containsAll(initialSelectedValues)),
|
||||
'Initial values are not all present in the items!',
|
||||
),
|
||||
super(
|
||||
key: key,
|
||||
);
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final List<T>? initialSelectedValues;
|
||||
final Function(List<T> selectedItems)? onChanged;
|
||||
//s1 -- Configuration
|
||||
final AstromicChipSelectorConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final double? itemSpacing;
|
||||
final double? runSpacing;
|
||||
//
|
||||
//s1 -- Content
|
||||
final List<(T item, bool isEnabled)> items;
|
||||
final Widget Function(T item, bool isEnabled, bool isSelected, VoidCallback? onTap, VoidCallback? onClearTapped) itemBuilder;
|
||||
final Widget Function(List<Widget> items)? groupBuilder;
|
||||
|
||||
@override
|
||||
State<AstromicChipSelector<T>> createState() => _AstromicChipSelectorState<T>();
|
||||
@@ -80,7 +80,7 @@ class _AstromicChipSelectorState<T> extends State<AstromicChipSelector<T>> {
|
||||
//s1 --Controllers & Listeners
|
||||
//
|
||||
//s1 --State
|
||||
selectedItems = widget.initialSelectedValues ?? [];
|
||||
selectedItems = widget.initialSelectedValues ?? <T>[];
|
||||
//s1 --State
|
||||
//
|
||||
//s1 --Late & Async Initializers
|
||||
@@ -126,7 +126,7 @@ class _AstromicChipSelectorState<T> extends State<AstromicChipSelector<T>> {
|
||||
//s1 -Values
|
||||
//
|
||||
//s1 -Widgets
|
||||
List<Widget> baseChildren = widget.items.map((currentItem) {
|
||||
List<Widget> baseChildren = widget.items.map(((T, bool) currentItem) {
|
||||
//
|
||||
AstromicChipSelectorConfiguration configuration = widget.configuration ?? const AstromicChipSelectorConfiguration();
|
||||
//
|
||||
|
||||
@@ -3,15 +3,6 @@ import 'package:flutter/widgets.dart';
|
||||
/// Configuration model for the chip selector element.
|
||||
|
||||
class AstromicChipSelectorConfiguration {
|
||||
final bool isNullable;
|
||||
final bool isWrap;
|
||||
final WrapAlignment wrapMainAllignment;
|
||||
final WrapCrossAlignment wrapCrossAllignment;
|
||||
final bool isConsequent;
|
||||
final bool withClearButton;
|
||||
final int maxSelectedItems;
|
||||
final int crossAxisCount;
|
||||
final double? fixedRowHeight;
|
||||
const AstromicChipSelectorConfiguration({
|
||||
this.isNullable = true,
|
||||
//
|
||||
@@ -24,6 +15,15 @@ class AstromicChipSelectorConfiguration {
|
||||
this.crossAxisCount = 3,
|
||||
this.fixedRowHeight,
|
||||
});
|
||||
final bool isNullable;
|
||||
final bool isWrap;
|
||||
final WrapAlignment wrapMainAllignment;
|
||||
final WrapCrossAlignment wrapCrossAllignment;
|
||||
final bool isConsequent;
|
||||
final bool withClearButton;
|
||||
final int maxSelectedItems;
|
||||
final int crossAxisCount;
|
||||
final double? fixedRowHeight;
|
||||
|
||||
AstromicChipSelectorConfiguration copyWith({
|
||||
bool? isNullable,
|
||||
|
||||
@@ -2,12 +2,6 @@ import 'package:flutter/widgets.dart';
|
||||
|
||||
/// Configuration model for the radio selector element.
|
||||
class AstromicRadioSelectorConfiguration {
|
||||
final Axis axis;
|
||||
final bool isNullable;
|
||||
//
|
||||
final MainAxisAlignment? mainAxisAlignment;
|
||||
final MainAxisSize? mainAxisSize;
|
||||
final CrossAxisAlignment? crossAxisAlignment;
|
||||
const AstromicRadioSelectorConfiguration({
|
||||
this.axis = Axis.horizontal,
|
||||
this.isNullable = true,
|
||||
@@ -16,6 +10,12 @@ class AstromicRadioSelectorConfiguration {
|
||||
this.mainAxisSize,
|
||||
this.crossAxisAlignment,
|
||||
});
|
||||
final Axis axis;
|
||||
final bool isNullable;
|
||||
//
|
||||
final MainAxisAlignment? mainAxisAlignment;
|
||||
final MainAxisSize? mainAxisSize;
|
||||
final CrossAxisAlignment? crossAxisAlignment;
|
||||
|
||||
AstromicRadioSelectorConfiguration copyWith({
|
||||
Axis? axis,
|
||||
|
||||
@@ -12,17 +12,6 @@ import 'models/models.exports.dart';
|
||||
|
||||
/// Selector that allows only one item to be selected from a group of items.
|
||||
class AstromicRadioSelector<T> extends StatefulWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final T? initialSelectedValue;
|
||||
final Function(T selectedItem)? onChanged;
|
||||
//s1 -- Configuration
|
||||
final AstromicRadioSelectorConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final double? itemSpacing;
|
||||
//s1 -- Content
|
||||
final List<(T item, bool isEnabled)> items;
|
||||
final Widget Function(T item, bool isEnabled, bool isSelected, VoidCallback? onTap) itemBuilder;
|
||||
//!SECTION
|
||||
//
|
||||
AstromicRadioSelector({
|
||||
@@ -42,16 +31,27 @@ class AstromicRadioSelector<T> extends StatefulWidget {
|
||||
configuration!.isNullable ||
|
||||
(items
|
||||
.map(
|
||||
(e) => e.$1,
|
||||
((T, bool) e) => e.$1,
|
||||
)
|
||||
.toList()
|
||||
.contains(initialSelectedValue) &&
|
||||
items.where((e) => e.$1 == initialSelectedValue).first.$2),
|
||||
"Initial value is not present in the items or is not enabled!",
|
||||
items.where(((T, bool) e) => e.$1 == initialSelectedValue).first.$2),
|
||||
'Initial value is not present in the items or is not enabled!',
|
||||
),
|
||||
super(
|
||||
key: key,
|
||||
);
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
final T? initialSelectedValue;
|
||||
final Function(T selectedItem)? onChanged;
|
||||
//s1 -- Configuration
|
||||
final AstromicRadioSelectorConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final double? itemSpacing;
|
||||
//s1 -- Content
|
||||
final List<(T item, bool isEnabled)> items;
|
||||
final Widget Function(T item, bool isEnabled, bool isSelected, VoidCallback? onTap) itemBuilder;
|
||||
|
||||
@override
|
||||
State<AstromicRadioSelector<T>> createState() => _AstromicRadioSelectorState<T>();
|
||||
@@ -116,7 +116,7 @@ class _AstromicRadioSelectorState<T> extends State<AstromicRadioSelector<T>> {
|
||||
//s1 -Values
|
||||
//
|
||||
//s1 -Widgets
|
||||
List<Widget> baseChildren = widget.items.map((currentItem) {
|
||||
List<Widget> baseChildren = widget.items.map(((T, bool) currentItem) {
|
||||
T item = currentItem.$1;
|
||||
bool isEnabled = currentItem.$2;
|
||||
bool isSelected = item == selectedItem;
|
||||
|
||||
@@ -12,20 +12,6 @@ import '../models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicCheckboxToggle extends StatefulWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
/// If provided, you have to change the variable yourself in the onStateChanged!
|
||||
final bool? stateVariable;
|
||||
final bool? initialState;
|
||||
final void Function(bool)? onStateChanged;
|
||||
//s1 -- Configuration
|
||||
final AstromicToggleConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final AstromicCheckboxToggleStyle Function(bool isEnabled, bool isSelected)? style;
|
||||
//
|
||||
//s1 -- Content
|
||||
final Widget Function(bool isEnabled, bool isSelected)? innerWidget;
|
||||
final Widget Function(bool isEnabled, bool isSelected)? label;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicCheckboxToggle({
|
||||
@@ -42,6 +28,20 @@ class AstromicCheckboxToggle extends StatefulWidget {
|
||||
this.innerWidget,
|
||||
this.label,
|
||||
}) : assert(stateVariable == null || initialState == null, "Can't define both the state variable and the initial state");
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
/// If provided, you have to change the variable yourself in the onStateChanged!
|
||||
final bool? stateVariable;
|
||||
final bool? initialState;
|
||||
final void Function(bool)? onStateChanged;
|
||||
//s1 -- Configuration
|
||||
final AstromicToggleConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final AstromicCheckboxToggleStyle Function(bool isEnabled, bool isSelected)? style;
|
||||
//
|
||||
//s1 -- Content
|
||||
final Widget Function(bool isEnabled, bool isSelected)? innerWidget;
|
||||
final Widget Function(bool isEnabled, bool isSelected)? label;
|
||||
|
||||
@override
|
||||
State<AstromicCheckboxToggle> createState() => _AstromicCheckboxToggleState();
|
||||
@@ -129,7 +129,7 @@ class _AstromicCheckboxToggleState extends State<AstromicCheckboxToggle> {
|
||||
textDirection: _config.textDirection,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
//Item
|
||||
SizedBox(
|
||||
width: _style.itemSize,
|
||||
|
||||
@@ -2,6 +2,14 @@ import 'package:flutter/material.dart';
|
||||
|
||||
/// Styling model for the CheckBox Toggle element.
|
||||
class AstromicCheckboxToggleStyle {
|
||||
|
||||
AstromicCheckboxToggleStyle({
|
||||
this.itemSize = 24.0,
|
||||
this.labelSpacing = 8.0,
|
||||
this.border = const Border.fromBorderSide(BorderSide(width: 2)),
|
||||
this.borderRadius = const BorderRadius.all(Radius.circular(4)),
|
||||
this.backgroundColor = Colors.transparent,
|
||||
});
|
||||
final double? itemSize;
|
||||
final double? labelSpacing;
|
||||
//
|
||||
@@ -9,14 +17,6 @@ class AstromicCheckboxToggleStyle {
|
||||
final BorderRadius? borderRadius;
|
||||
final Color? backgroundColor;
|
||||
|
||||
AstromicCheckboxToggleStyle({
|
||||
this.itemSize = 24.0,
|
||||
this.labelSpacing = 8.0,
|
||||
this.border = const Border.fromBorderSide(BorderSide(width: 2, color: Colors.black)),
|
||||
this.borderRadius = const BorderRadius.all(Radius.circular(4)),
|
||||
this.backgroundColor = Colors.transparent,
|
||||
});
|
||||
|
||||
AstromicCheckboxToggleStyle copyWith({
|
||||
double? itemSize,
|
||||
double? labelSpacing,
|
||||
|
||||
@@ -2,24 +2,6 @@ import 'package:flutter/widgets.dart';
|
||||
|
||||
/// Styling model for the Switcher Toggle element.
|
||||
class AstromicSwitcherToggleStyle {
|
||||
final double width;
|
||||
final double height;
|
||||
final double labelSpacing;
|
||||
final double toggleSize;
|
||||
final double togglePadding;
|
||||
final double borderRadius;
|
||||
//
|
||||
final Color activeColor;
|
||||
final Color? activeToggleColor;
|
||||
final BoxBorder? activeToggleBorder;
|
||||
final BoxBorder? activeSwitchBorder;
|
||||
final Widget? innerActiveWidget;
|
||||
//
|
||||
final Color inactiveColor;
|
||||
final Color? inactiveToggleColor;
|
||||
final BoxBorder? inactiveSwitchBorder;
|
||||
final BoxBorder? inactiveToggleBorder;
|
||||
final Widget? innerInactiveWidget;
|
||||
//
|
||||
const AstromicSwitcherToggleStyle({
|
||||
this.width = 70,
|
||||
@@ -39,4 +21,22 @@ class AstromicSwitcherToggleStyle {
|
||||
this.innerActiveWidget,
|
||||
this.innerInactiveWidget,
|
||||
});
|
||||
final double width;
|
||||
final double height;
|
||||
final double labelSpacing;
|
||||
final double toggleSize;
|
||||
final double togglePadding;
|
||||
final double borderRadius;
|
||||
//
|
||||
final Color activeColor;
|
||||
final Color? activeToggleColor;
|
||||
final BoxBorder? activeToggleBorder;
|
||||
final BoxBorder? activeSwitchBorder;
|
||||
final Widget? innerActiveWidget;
|
||||
//
|
||||
final Color inactiveColor;
|
||||
final Color? inactiveToggleColor;
|
||||
final BoxBorder? inactiveSwitchBorder;
|
||||
final BoxBorder? inactiveToggleBorder;
|
||||
final Widget? innerInactiveWidget;
|
||||
}
|
||||
|
||||
@@ -13,18 +13,6 @@ import '../models/models.exports.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicSwitcherToggle extends StatefulWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
/// If provided, you have to change the variable yourself in the onStateChanged!
|
||||
final bool? stateVariable;
|
||||
final bool? initialState;
|
||||
final void Function(bool)? onStateChanged;
|
||||
//s1 -- Configuration
|
||||
final AstromicToggleConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final AstromicSwitcherToggleStyle Function(bool isEnabled, bool isSelected)? style;
|
||||
//s1 -- Content
|
||||
final Widget Function(bool isEnabled, bool isSelected)? label;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicSwitcherToggle({
|
||||
@@ -39,6 +27,18 @@ class AstromicSwitcherToggle extends StatefulWidget {
|
||||
//
|
||||
this.label,
|
||||
});
|
||||
//SECTION - Widget Arguments
|
||||
//s1 -- Functionality
|
||||
/// If provided, you have to change the variable yourself in the onStateChanged!
|
||||
final bool? stateVariable;
|
||||
final bool? initialState;
|
||||
final void Function(bool)? onStateChanged;
|
||||
//s1 -- Configuration
|
||||
final AstromicToggleConfiguration? configuration;
|
||||
//s1 -- Style
|
||||
final AstromicSwitcherToggleStyle Function(bool isEnabled, bool isSelected)? style;
|
||||
//s1 -- Content
|
||||
final Widget Function(bool isEnabled, bool isSelected)? label;
|
||||
|
||||
@override
|
||||
State<AstromicSwitcherToggle> createState() => AstromicSwitcherToggleState();
|
||||
@@ -111,7 +111,7 @@ class AstromicSwitcherToggleState extends State<AstromicSwitcherToggle> {
|
||||
textDirection: _config.textDirection,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
//S1 -- Item
|
||||
FlutterSwitch(
|
||||
width: _style.width,
|
||||
@@ -119,7 +119,6 @@ class AstromicSwitcherToggleState extends State<AstromicSwitcherToggle> {
|
||||
borderRadius: _style.borderRadius,
|
||||
value: _currentState,
|
||||
toggleSize: _style.toggleSize,
|
||||
disabled: false,
|
||||
//
|
||||
activeColor: _style.activeColor,
|
||||
activeToggleColor: _style.activeToggleColor,
|
||||
@@ -134,8 +133,7 @@ class AstromicSwitcherToggleState extends State<AstromicSwitcherToggle> {
|
||||
inactiveIcon: _style.innerInactiveWidget,
|
||||
//
|
||||
padding: _style.togglePadding,
|
||||
showOnOff: false,
|
||||
onToggle: (s) => _onTap(s),
|
||||
onToggle: (bool s) => _onTap(s),
|
||||
),
|
||||
//S1 -- Label Spacing
|
||||
if (_config.withLabel) SizedBox(width: _style.labelSpacing),
|
||||
|
||||
@@ -2,16 +2,16 @@ import 'dart:ui';
|
||||
|
||||
/// SConfiguration model for the Toggles element group.
|
||||
class AstromicToggleConfiguration {
|
||||
final bool isEnabled;
|
||||
final bool withLabel;
|
||||
final bool isLabelTapable;
|
||||
final TextDirection textDirection;
|
||||
AstromicToggleConfiguration({
|
||||
this.isEnabled = true,
|
||||
this.withLabel = false,
|
||||
this.isLabelTapable = true,
|
||||
this.textDirection = TextDirection.ltr,
|
||||
});
|
||||
final bool isEnabled;
|
||||
final bool withLabel;
|
||||
final bool isLabelTapable;
|
||||
final TextDirection textDirection;
|
||||
|
||||
AstromicToggleConfiguration copyWith({
|
||||
bool? isEnabled,
|
||||
|
||||
@@ -11,15 +11,6 @@ import 'package:flutter/material.dart';
|
||||
//s1 Exports
|
||||
|
||||
class AstromicBlur extends StatelessWidget {
|
||||
//SECTION - Widget Arguments
|
||||
final Widget child;
|
||||
final (double x, double y)? sigma;
|
||||
final TileMode? tileMode;
|
||||
final Color? overlayColor;
|
||||
final Gradient? overlayGradient;
|
||||
final BorderRadius? radius;
|
||||
final List<BoxShadow>? shadow;
|
||||
final Widget? childOnTop;
|
||||
//!SECTION
|
||||
//
|
||||
const AstromicBlur({
|
||||
@@ -33,6 +24,15 @@ class AstromicBlur extends StatelessWidget {
|
||||
this.shadow,
|
||||
this.childOnTop,
|
||||
});
|
||||
//SECTION - Widget Arguments
|
||||
final Widget child;
|
||||
final (double x, double y)? sigma;
|
||||
final TileMode? tileMode;
|
||||
final Color? overlayColor;
|
||||
final Gradient? overlayGradient;
|
||||
final BorderRadius? radius;
|
||||
final List<BoxShadow>? shadow;
|
||||
final Widget? childOnTop;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -56,7 +56,7 @@ class AstromicBlur extends StatelessWidget {
|
||||
borderRadius: radius ?? BorderRadius.zero,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
child, // The main widget goes under the blurred background
|
||||
BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: sigma!.$1, sigmaY: sigma!.$2),
|
||||
|
||||
@@ -47,42 +47,6 @@ _DeclaredAssetType _parseAssetType(
|
||||
}
|
||||
|
||||
class AstromicImage extends StatelessWidget {
|
||||
//SECTION - Widget Arguments
|
||||
//S1 -- Assets
|
||||
final String? assetPath;
|
||||
final String? assetURL;
|
||||
final Uint8List? assetBytes;
|
||||
final String? assetFallback;
|
||||
//S1 -- Sizing
|
||||
final ImageSizingMaster? sizingMaster;
|
||||
final (double factor, double? min, double? max)? widthSizing;
|
||||
|
||||
/// Used when the width is Master and want to set fixed width OR if height is Master and want to constraint the width
|
||||
final double? fixedWidth;
|
||||
final (double factor, double? min, double? max)? heightSizing;
|
||||
|
||||
/// Used when the height is Master and want to set fixed height OR if width is Master and want to constraint the height
|
||||
final double? fixedHeight;
|
||||
//S1 -- STYLING
|
||||
final bool? isCircular;
|
||||
final double? borderWidth;
|
||||
final Color? borderColor;
|
||||
final EdgeInsetsGeometry? borderPadding;
|
||||
final BorderRadiusGeometry? radius;
|
||||
final List<BoxShadow>? shadow;
|
||||
final Color? overlayColor;
|
||||
final Gradient? overlayGradient;
|
||||
//S1 -- CONFIGURATIONS
|
||||
final Alignment? alignment;
|
||||
final BoxFit? fit;
|
||||
final BlendMode? blendMode;
|
||||
final Curve? fadeInCurve;
|
||||
final Duration? fadeInDuration;
|
||||
//S1 -- SVG FILTERS
|
||||
final Color? svgColor;
|
||||
//S1 -- STATE WIDGETS
|
||||
final Widget Function(int? loadedBytes, int? totalBytesToLoad)? loadingWidget;
|
||||
final Widget Function(dynamic error, StackTrace? stackTrace)? errorWidget;
|
||||
//!SECTION
|
||||
//
|
||||
AstromicImage({
|
||||
@@ -121,16 +85,52 @@ class AstromicImage extends StatelessWidget {
|
||||
}) :
|
||||
// Assert that a source is provided, or provide a fallback source..
|
||||
assert(((assetPath?.isNotEmpty ?? false) || (assetURL?.isNotEmpty ?? false) || (assetBytes?.isNotEmpty ?? false)) || (assetFallback?.isNotEmpty ?? false),
|
||||
"Please specify a source or provide a fallback."),
|
||||
'Please specify a source or provide a fallback.'),
|
||||
// Assert that only ONE source is provided...
|
||||
assert(
|
||||
(assetPath != null && assetBytes == null && assetURL == null) ||
|
||||
(assetPath == null && assetBytes != null && assetURL == null) ||
|
||||
(assetPath == null && assetBytes == null && assetURL != null),
|
||||
"Please specify only ONE Asset Source"),
|
||||
'Please specify only ONE Asset Source'),
|
||||
// Assert that correct sizing plan is provided...
|
||||
assert((sizingMaster == ImageSizingMaster.w && (widthSizing != null || fixedWidth != null)) || (sizingMaster == ImageSizingMaster.h && (heightSizing != null || fixedHeight != null)),
|
||||
"Please provide the correct sizing configurations based on the SizingMaster choosen");
|
||||
'Please provide the correct sizing configurations based on the SizingMaster choosen');
|
||||
//SECTION - Widget Arguments
|
||||
//S1 -- Assets
|
||||
final String? assetPath;
|
||||
final String? assetURL;
|
||||
final Uint8List? assetBytes;
|
||||
final String? assetFallback;
|
||||
//S1 -- Sizing
|
||||
final ImageSizingMaster? sizingMaster;
|
||||
final (double factor, double? min, double? max)? widthSizing;
|
||||
|
||||
/// Used when the width is Master and want to set fixed width OR if height is Master and want to constraint the width
|
||||
final double? fixedWidth;
|
||||
final (double factor, double? min, double? max)? heightSizing;
|
||||
|
||||
/// Used when the height is Master and want to set fixed height OR if width is Master and want to constraint the height
|
||||
final double? fixedHeight;
|
||||
//S1 -- STYLING
|
||||
final bool? isCircular;
|
||||
final double? borderWidth;
|
||||
final Color? borderColor;
|
||||
final EdgeInsetsGeometry? borderPadding;
|
||||
final BorderRadiusGeometry? radius;
|
||||
final List<BoxShadow>? shadow;
|
||||
final Color? overlayColor;
|
||||
final Gradient? overlayGradient;
|
||||
//S1 -- CONFIGURATIONS
|
||||
final Alignment? alignment;
|
||||
final BoxFit? fit;
|
||||
final BlendMode? blendMode;
|
||||
final Curve? fadeInCurve;
|
||||
final Duration? fadeInDuration;
|
||||
//S1 -- SVG FILTERS
|
||||
final Color? svgColor;
|
||||
//S1 -- STATE WIDGETS
|
||||
final Widget Function(int? loadedBytes, int? totalBytesToLoad)? loadingWidget;
|
||||
final Widget Function(dynamic error, StackTrace? stackTrace)? errorWidget;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -152,7 +152,7 @@ class AstromicImage extends StatelessWidget {
|
||||
Widget? finalSVGWidget(Size size, Widget? loadingWidget) => assetType == _DeclaredAssetType.path
|
||||
? SvgPicture.asset(
|
||||
assetRef,
|
||||
key: ValueKey(assetRef),
|
||||
key: ValueKey<String>(assetRef),
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
fit: fit!,
|
||||
@@ -167,7 +167,7 @@ class AstromicImage extends StatelessWidget {
|
||||
: assetType == _DeclaredAssetType.url
|
||||
? SvgPicture.network(
|
||||
assetRef,
|
||||
key: ValueKey(assetRef),
|
||||
key: ValueKey<String>(assetRef),
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
fit: fit!,
|
||||
@@ -183,9 +183,9 @@ class AstromicImage extends StatelessWidget {
|
||||
|
||||
Widget buildImage(Size size) {
|
||||
return Stack(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
OctoImage(
|
||||
key: ValueKey(assetType == _DeclaredAssetType.bytes ? (assetRef as Uint8List).length.toString() : assetRef),
|
||||
key: ValueKey<String>(assetType == _DeclaredAssetType.bytes ? (assetRef as Uint8List).length.toString() : assetRef),
|
||||
//
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
@@ -195,8 +195,8 @@ class AstromicImage extends StatelessWidget {
|
||||
color: svgColor,
|
||||
colorBlendMode: blendMode ?? (isSVG ? BlendMode.srcATop : null),
|
||||
//
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
debugPrint("AstromicImage Error: $error");
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
|
||||
debugPrint('AstromicImage Error: $error');
|
||||
return errorWidget != null
|
||||
? errorWidget!(error, stackTrace)
|
||||
: assetFallback != null
|
||||
@@ -204,15 +204,15 @@ class AstromicImage extends StatelessWidget {
|
||||
: defaultErrorWidget(error);
|
||||
},
|
||||
//
|
||||
progressIndicatorBuilder: (_, bytes) => SizedBox(
|
||||
progressIndicatorBuilder: (_, ImageChunkEvent? bytes) => SizedBox(
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
child: loadingWidget != null ? loadingWidget!(bytes?.cumulativeBytesLoaded, bytes?.expectedTotalBytes) : defaultLoadingWidget,
|
||||
),
|
||||
placeholderBuilder: (context) => loadingWidget != null ? loadingWidget!(null, null) : defaultLoadingWidget,
|
||||
placeholderBuilder: (BuildContext context) => loadingWidget != null ? loadingWidget!(null, null) : defaultLoadingWidget,
|
||||
fadeInCurve: fadeInCurve,
|
||||
fadeInDuration: fadeInDuration,
|
||||
imageBuilder: (context, image) => Container(
|
||||
imageBuilder: (BuildContext context, Widget image) => Container(
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
padding: borderPadding ?? EdgeInsets.zero,
|
||||
@@ -220,7 +220,6 @@ class AstromicImage extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
border: borderWidth != null
|
||||
? Border.all(
|
||||
strokeAlign: BorderSide.strokeAlignInside,
|
||||
width: borderWidth!,
|
||||
color: borderColor ?? const Color(0xff000000),
|
||||
)
|
||||
@@ -250,7 +249,7 @@ class AstromicImage extends StatelessWidget {
|
||||
//!SECTION
|
||||
|
||||
//SECTION - Build Return
|
||||
return LayoutBuilder(builder: (context, constraints) {
|
||||
return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
|
||||
Size size = _calculateSize(constraints);
|
||||
return SizedBox(width: size.width, height: size.height, child: buildImage(size));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user