This commit is contained in:
2025-03-30 12:16:43 +02:00
parent 11aee47f80
commit 97020cf117
9 changed files with 160 additions and 18 deletions

View File

@@ -10,3 +10,11 @@ extension InsetsExtension on EdgeInsetsGeometry {
//
}
}
extension InsetsNumExtension on num {
EdgeInsets get symH => EdgeInsets.symmetric(horizontal: toDouble());
EdgeInsets get symV => EdgeInsets.symmetric(vertical: toDouble());
EdgeInsets get padAll => EdgeInsets.all(toDouble());
EdgeInsets get padTop => EdgeInsets.only(top: toDouble());
EdgeInsets get padBot => EdgeInsets.only(bottom: toDouble());
}

View File

@@ -0,0 +1,113 @@
import 'dart:math' as math;
import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
import 'insets_extension.dart';
extension StringWidgetExtensions on String {
/// Convert this text into a RichText with custom quick styles and tap gestures.
RichText rich(TextStyle masterStyle, {Map<int, TextStyle>? styles, Map<int, VoidCallback>? tapCallbacks, TextAlign textAlign = TextAlign.center}) {
Map<String, TextStyle> mappedStyles = <String, TextStyle>{};
Map<String, VoidCallback> mappedCallbacks = <String, VoidCallback>{};
// Getting string pieces.
List<String> stringPieces = RegExp(r'`([^`]*)`').allMatches(this).map((RegExpMatch m) => m.group(1)).whereType<String>().toList();
// Looping on the pieces...
for (String stringPiece in stringPieces) {
String textAfter = split('`$stringPiece`')[1];
String textBeforeNext = textAfter.split('`')[0];
if (RegExp(r'{(\d+)}').hasMatch(textBeforeNext)) {
// The current piece has an index
int? itemIndex = int.tryParse(RegExp(r'{(\d+)}').allMatches(textBeforeNext).map((RegExpMatch m) => m.group(1)).whereType<String>().first);
if (itemIndex != null) {
// Styles
if (styles != null && styles.isNotEmpty && styles.keys.contains(itemIndex)) {
// Custom Style
mappedStyles.addEntries(<MapEntry<String, TextStyle>>[MapEntry<String, TextStyle>(stringPiece, styles[itemIndex]!)]);
} else {
// Master
mappedStyles.addEntries(<MapEntry<String, TextStyle>>[MapEntry<String, TextStyle>(stringPiece, masterStyle)]);
}
// Callbacks
if (tapCallbacks != null && tapCallbacks.isNotEmpty && tapCallbacks.keys.contains(itemIndex)) {
// Add tap callbak
mappedCallbacks.addEntries(<MapEntry<String, VoidCallback>>[MapEntry<String, VoidCallback>(stringPiece, tapCallbacks[itemIndex]!)]);
}
} else {
debugPrint('Something wrong with applying custom indexing in QuickRichText. $itemIndex');
}
} else {
mappedStyles.addEntries(<MapEntry<String, TextStyle>>[MapEntry<String, TextStyle>(stringPiece, masterStyle)]);
}
}
// Adding styles to the children
List<InlineSpan> children = mappedStyles.entries
.toList()
.sublist(1)
.map((MapEntry<String, TextStyle> entry) => TextSpan(
text: entry.key,
style: entry.value,
recognizer: mappedCallbacks.containsKey(entry.key) ? (TapGestureRecognizer()..onTap = mappedCallbacks[entry.key]) : null,
))
.toList();
return RichText(
text: TextSpan(
text: stringPieces[0],
style: masterStyle,
children: children,
),
textAlign: textAlign,
);
}
}
extension QuickSimpleWidgets on Widget {
/// Center the widget
Widget get center => Center(child: this);
/// Make the widget circular with RRect
Widget get circular => ClipRRect(borderRadius: BorderRadius.circular(10000000), child: this);
/// Wrap with a SizedBox
Widget sized({num? w, num? h}) => SizedBox(width: w?.toDouble(), height: h?.toDouble(), child: this);
/// Wrap with a Positioned
Widget positioned({num? bottom, num? top}) => Positioned(bottom: bottom?.toDouble(), top: top?.toDouble(), child: this);
/// Rotate the widget in quarter turns
Widget rotated({int quarterTurns = 0}) => Transform.rotate(angle: (math.pi * 22.5) * quarterTurns, child: this);
//TODO - Make it directional
/// Align
Widget align(Alignment a) => Align(alignment: a, child: this);
/// Flip the widget horizontally
Widget get flipH => Transform.flip(flipX: true, child: this);
/// Flip the widget vertically
Widget get flipV => Transform.flip(flipY: true, child: this);
/// Wrap with a SafeArea
Widget get safeArea => SafeArea(child: this);
/// Quick Opacity Adjustment
Widget opacity(num o) => Opacity(opacity: o.toDouble(), child: this);
/// Padding padAll
Widget padAll(num p) => Padding(padding: p.padAll, child: this);
/// Padding Symmetric Horizontally
Widget padSymH(num p) => Padding(padding: p.symH, child: this);
/// Padding Symmetric Vertically
Widget padSymV(num p) => Padding(padding: p.symV, child: this);
//
/// Padding Only Top
Widget padTop(num p) => Padding(padding: p.padTop, child: this);
/// Padding Only Bottom
Widget padBot(num p) => Padding(padding: p.padBot, child: this);
}