diff --git a/packages/rfw/lib/src/flutter/argument_decoders.dart b/packages/rfw/lib/src/flutter/argument_decoders.dart index 41db3bf95b96..c73554cdf8d2 100644 --- a/packages/rfw/lib/src/flutter/argument_decoders.dart +++ b/packages/rfw/lib/src/flutter/argument_decoders.dart @@ -9,8 +9,6 @@ // This file is hand-formatted. import 'dart:math' as math show pi; -// ignore: unnecessary_import, see https://github.com/flutter/flutter/pull/138881 -import 'dart:ui' show FontFeature; // TODO(ianh): https://github.com/flutter/flutter/issues/87235 import 'package:flutter/material.dart'; @@ -91,6 +89,12 @@ class ArgumentDecoders { /// If the map has `start` and `y` keys, then it is interpreted as an /// [AlignmentDirectional] with those values. Otherwise if it has `x` and `y` /// it's an [Alignment] with those values. Otherwise it returns null. + /// + /// For example: + /// + /// ```rfwtxt + /// { start: 12.0, y: 5.0 } // AlignmentDirectional(12.0, 5.0) + /// ``` static AlignmentGeometry? alignment(DataSource source, List key) { if (!source.isMap(key)) { return null; @@ -115,6 +119,12 @@ class ArgumentDecoders { /// /// The keys used are `minWidth`, `maxWidth`, `minHeight`, and `maxHeight`. /// Omitted keys are defaulted to 0.0 for minimums and infinity for maximums. + /// + /// For example: + /// + /// ```rfwtxt + /// { minWidth: 10.0 } // BoxConstraints(minWidth: 10.0) + /// ``` static BoxConstraints? boxConstraints(DataSource source, List key) { if (!source.isMap(key)) { return null; @@ -139,6 +149,18 @@ class ArgumentDecoders { /// * top: second value, defaulting to same as start. /// * end: third value, defaulting to same as start. /// * bottom: fourth value, defaulting to same as top. + /// + /// For example: + /// + /// ```rfwtxt + /// [ { color: 0xFF00FFFF, width: 0.0 }, { style: 'none' } ] + /// // BorderDirectional( + /// // start: BorderSide(color: Color(0xFF00FFFF), width: 0.0), + /// // top: BorderSide(style: BorderStyle.none), + /// // end: BorderSide(color: Color(0xFF00FFFF), width: 0.0), + /// // bottom: BorderSide(style: BorderStyle.none), + /// // ) + /// ``` static BoxBorder? border(DataSource source, List key) { final BorderSide? a = borderSide(source, [...key, 0]); if (a == null) { @@ -167,6 +189,18 @@ class ArgumentDecoders { /// * topEnd: second value, defaulting to same as topStart. /// * bottomStart: third value, defaulting to same as topStart. /// * bottomEnd: fourth value, defaulting to same as topEnd. + /// + /// For example: + /// + /// ```rfwtxt + /// [ { x: 20.0 }, { x: 5.0, y: 10.0 }, { x: 0.0 } ] + /// // BorderRadiusDirectional.only( + /// // topStart: Radius.circular(20.0), + /// // topEnd: Radius.elliptical(5.0, 10.0), + /// // bottomStart: Radius.circular(0.0), + /// // bottomEnd: Radius.elliptical(5.0, 10.0), + /// // ) + /// ``` static BorderRadiusGeometry? borderRadius(DataSource source, List key) { final Radius? a = radius(source, [...key, 0]); if (a == null) { @@ -191,6 +225,12 @@ class ArgumentDecoders { /// keys `color` (see [color], defaults to black), `width` (a double, defaults /// to 1.0), and `style` (see [enumValue] for [BorderStyle], defaults to /// [BorderStyle.solid]). + /// + /// For example: + /// + /// ```rfwtxt + /// { color: 0xFF00FFFF, width: 0.0 } // BorderSide(color: Color(0xFF00FFFF), width: 0.0) + /// ``` static BorderSide? borderSide(DataSource source, List key) { if (!source.isMap(key)) { return null; @@ -210,6 +250,16 @@ class ArgumentDecoders { /// keys `color` (see [color], defaults to black), `offset` (see [offset], /// defaults to [Offset.zero]), `blurRadius` (double, defaults to zero), and /// `spreadRadius` (double, defaults to zero). + /// + /// For example: + /// + /// ```rfwtxt + /// { offset: { x: 2.0, y: 2.0 }, blurRadius: 5.0 } + /// // BoxShadow( + /// // offset: const Offset(2.0, 2.0), + /// // blurRadius: 5.0, + /// // ), + /// ``` static BoxShadow boxShadow(DataSource source, List key) { if (!source.isMap(key)) { return const BoxShadow(); @@ -224,8 +274,10 @@ class ArgumentDecoders { /// Returns a [Color] from the specified integer. /// - /// Returns null if it's not an integer; otherwise, passes it to the [ - /// Color] constructor. + /// Returns null if it's not an integer; otherwise, passes it to the + /// [Color] constructor. + /// + /// For example, 0xFFFF9900 is opaque orange. static Color? color(DataSource source, List key) { final int? value = source.v(key); if (value == null) { @@ -254,6 +306,13 @@ class ArgumentDecoders { /// that callback. /// /// Otherwise, returns null. + /// + /// For example: + /// + /// ```rfwtxt + /// { type: 'mode', color: 0xFFFFFFFF, blendMode: 'xor' } + /// // ColorFilter.mode(const Color(0xFFFFFFFF), BlendMode.xor) + /// ``` static ColorFilter? colorFilter(DataSource source, List key) { final String? type = source.v([...key, 'type']); switch (type) { @@ -324,12 +383,11 @@ class ArgumentDecoders { /// Returns a [Color] from the specified integer. /// - /// Returns black if it's not an integer; otherwise, passes it to the [ - /// Color] constructor. + /// Returns black if it's not an integer; otherwise, passes it to the + /// [Color] constructor. /// /// This is useful in situations where null is not acceptable, for example, - /// when providing a decoder to [list]. Otherwise, prefer using [DataSource.v] - /// directly. + /// when providing a decoder to [list]. Otherwise, prefer using [color]. static Color colorOrBlack(DataSource source, List key) { return color(source, key) ?? const Color(0xFF000000); } @@ -476,6 +534,20 @@ class ArgumentDecoders { /// that callback. /// /// Otherwise, returns null. + /// + /// For example: + /// + /// ```rfwtxt + /// { + /// type: 'shape', + /// color: 0xFF008080, + /// shape: { type: 'stadium' }, + /// } + /// // const ShapeDecoration( + /// // color: const Color(0xFF008080), + /// // shape: StadiumBorder(), + /// // ) + /// ``` static Decoration? decoration(DataSource source, List key) { final String? type = source.v([...key, 'type']); switch (type) { @@ -531,6 +603,13 @@ class ArgumentDecoders { /// ([alignment], defaults to [Alignment.center]), `centerSlice` ([rect]), /// `repeat` ([enumValue] of [ImageRepeat], defaults to [ImageRepeat.noRepeat]), /// `matchTextDirection` (boolean, defaults to false). + /// + /// For example: + /// + /// ```rfwtxt + /// { source: 'button.jpeg', fit: 'fill', centerSlice: { { x: 10.0, y: 10.0, w: 80.0, h: 80.0 } } } + /// // DecorationImage(image: AssetImage('button.jpeg'), fit: BoxFit.fill, centerSlice: Rect.fromLTWH(10, 10, 80, 80)) + /// ``` static DecorationImage? decorationImage(DataSource source, List key) { final ImageProvider? provider = imageProvider(source, key); if (provider == null) { @@ -564,7 +643,7 @@ class ArgumentDecoders { return source.v(key) ?? 0.0; } - /// Returns a [Duration] from the specified integer. + /// Returns a [Duration] from the specified integer, which specifies milliseconds. /// /// If it's not an integer, the default obtained from /// [AnimationDefaults.durationOf] is used (which is why a [BuildContext] is @@ -589,6 +668,14 @@ class ArgumentDecoders { /// * top: second value, defaulting to same as start. /// * end: third value, defaulting to same as start. /// * bottom: fourth value, defaulting to same as top. + /// + /// For example: + /// + /// ```rfwtxt + /// [ 5.0 ] // EdgeInsets.all(5.0) + /// [ 5.0, 2.0 ] // EdgeInsets.symmetric(horizontal: 5.0, vertical: 2.0) + /// [ 5.0, 2.0, 10.0 ] // EdgeInsets.fromLTRB(5.0, 2.0, 10.0, 2.0) + /// ``` static EdgeInsetsGeometry? edgeInsets(DataSource source, List key) { final double? a = source.v([...key, 0]); if (a == null) { @@ -637,6 +724,13 @@ class ArgumentDecoders { /// value (defaulting to 1, which typically means "enabled"). /// /// As this never returns null, it is possible to use it with [list]. + /// + /// For example: + /// + /// ```rfwtxt + /// { feature: 'numr' } // FontFeature.numerators() + /// { feature: 'nalt', value: 3 } // FontFeature.notationalForms(3) + /// ``` static FontFeature fontFeature(DataSource source, List key) { return FontFeature(source.v([...key, 'feature']) ?? 'NONE', source.v([...key, 'value']) ?? 1); } @@ -678,6 +772,13 @@ class ArgumentDecoders { /// that callback. /// /// Otherwise, returns null. + /// + /// For example: + /// + /// ```rfwtxt + /// { type: 'linear', 'colors': [ 0xFF000000, 0xFF0000FF ], tileMode: 'mirror' } + /// // LinearGradient(colors: [ Color(0xFF000000), Color(0xFF0000FF) ], tileMode: TileMode.mirror) + /// ``` static Gradient? gradient(DataSource source, List key) { final String? type = source.v([...key, 'type']); switch (type) { @@ -747,6 +848,13 @@ class ArgumentDecoders { /// that callback. /// /// Otherwise, returns null. + /// + /// For example: + /// + /// ```rfwtxt + /// { type: 'fixedCrossAxisCount', crossAxisCount: 3 } + /// // SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3) + /// ``` static SliverGridDelegate? gridDelegate(DataSource source, List key) { final String? type = source.v([...key, 'type']); switch (type) { @@ -797,6 +905,12 @@ class ArgumentDecoders { /// When building the release build of an application that uses the RFW /// package, because this method creates non-const [IconData] objects /// dynamically, the `--no-tree-shake-icons` option must be used. + /// + /// For example: + /// + /// ```rfwtxt + /// { icon: 0xE32A, fontFamily: 'MaterialIcons' } // Icons.houseboat + /// ``` static IconData? iconData(DataSource source, List key) { final int? icon = source.v([...key, 'icon']); if (icon == null) { @@ -844,6 +958,12 @@ class ArgumentDecoders { /// /// Otherwise, if there is no `source` key in the map, or if that cannot be /// parsed as a URL (absolute or relative), null is returned. + /// + /// For example: + /// + /// ```rfwtxt + /// { source: 'cats.png' } // AssetImage('cats.png') + /// ``` static ImageProvider? imageProvider(DataSource source, List key) { final String? image = source.v([...key, 'source']); if (image == null) { @@ -890,11 +1010,11 @@ class ArgumentDecoders { /// /// If the string is null, returns null. /// - /// If there is no hyphen in the list, uses the one-argument form of [ - /// Locale], passing the whole string. + /// If there is no hyphen in the list, uses the one-argument form of + /// [Locale], passing the whole string. /// - /// If there is one hyphen in the list, uses the two-argument form of [ - /// Locale], passing the parts before and after the hyphen respectively. + /// If there is one hyphen in the list, uses the two-argument form of + /// [Locale], passing the parts before and after the hyphen respectively. /// /// If there are two or more hyphens, uses the [Locale.fromSubtags] /// constructor. @@ -1096,6 +1216,12 @@ class ArgumentDecoders { /// (as in [Radius.circular]). /// /// If the `x` key is absent, the returned value is null. + /// + /// For example: + /// + /// ```rfwtxt + /// { x: 20.0 } // Radius.circular(20.0) + /// ``` static Radius? radius(DataSource source, List key) { final double? x = source.v([...key, 'x']); if (x == null) { @@ -1112,6 +1238,12 @@ class ArgumentDecoders { /// Otherwise, returns a [Rect.fromLTWH] whose x, y, width, and height /// components are determined from the `x`, `y`, `w`, and `h` properties of /// the map, with missing (or non-double) values replaced by zeros. + /// + /// For example: + /// + /// ```rfwtxt + /// { w: 300.0, h: 150.0 } // Rect.fromLTWH(0, 0, 300, 150) + /// ``` static Rect? rect(DataSource source, List key) { if (!source.isMap(key)) { return null; diff --git a/packages/rfw/lib/src/flutter/core_widgets.dart b/packages/rfw/lib/src/flutter/core_widgets.dart index a60e17f04073..b04ff526a0f2 100644 --- a/packages/rfw/lib/src/flutter/core_widgets.dart +++ b/packages/rfw/lib/src/flutter/core_widgets.dart @@ -8,9 +8,6 @@ // This file is hand-formatted. -// ignore: unnecessary_import, see https://github.com/flutter/flutter/pull/138881 -import 'dart:ui' show FontFeature; - import 'package:flutter/gestures.dart' show DragStartBehavior; import 'package:flutter/material.dart' show Icons; import 'package:flutter/widgets.dart'; @@ -64,29 +61,51 @@ import 'runtime.dart'; /// /// For each, every parameter is implemented using the same name. Parameters /// that take structured types are represented using maps, with each named -/// parameter of that type's default constructor represented by a key, with the -/// following notable caveats and exceptions: +/// parameter of that type's default constructor represented by a key. +/// +/// For example, a [TextStyle] argument of a [Text] widget would look like this: +/// +/// ```rfwtxt +/// Text( +/// text: 'hello', +/// style: { +/// fontSize: 12.0, +/// fontFamily: 'Arial', +/// color: 0xFF009900, // green; see discussion below +/// }, +/// ) +/// ``` +/// +/// Decoders are documented in more detail in [ArgumentDecoders]. +/// +/// The following notable caveats and exceptions apply: /// /// * Enums are represented as strings with the unqualified name of the value. /// For example, [MainAxisAlignment.start] is represented as the string -/// `"start"`. +/// `"start"`. See [ArgumentDecoders.enumValue]. /// /// * Types that have multiple subclasses (or multiple very unrelated -/// constructors, like [ColorFilter]) are represented as maps where the `type` -/// key specifies the type. Typically these have an extension mechanism. +/// constructors, like [ColorFilter]) are represented as maps where the +/// `type` key specifies the type. Typically these have an extension +/// mechanism. Examples include [ArgumentDecoders.colorFilter], +/// [ArgumentDecoders.decoration], [ArgumentDecoders.gradient], +/// [ArgumentDecoders.gridDelegate], [ArgumentDecoders.maskFilter], +/// [ArgumentDecoders.shapeBorder], and [ArgumentDecoders.shader]. /// /// * Matrices are represented as **column-major** flattened arrays. [Matrix4] -/// values must have exactly 16 doubles in the array. +/// values must have exactly 16 doubles in the array. See +/// [ArgumentDecoders.matrix] and [ArgumentDecoders.colorMatrix]. /// /// * [AlignmentGeometry] values can be represented either as `{x: ..., y: /// ...}` for a non-directional variant or `{start: ..., y: ...}` for a -/// directional variant. +/// directional variant. See [ArgumentDecoders.alignment]. /// /// * [BoxBorder] instances are defined as arrays of [BorderSide] maps. If the /// array has length 1, then that value is used for all four sides. Two /// values become the horizontal and vertical sides respectively. Three /// values become the start, top-and-bottom, and end respectively. Four -/// values become the start, top, end, and bottom respectively. +/// values become the start, top, end, and bottom respectively. See +/// [ArgumentDecoders.border]. /// /// * [BorderRadiusGeometry] values work similarly to [BoxBorder], as an array /// of [Radius] values. If the array has one value, it's used for all corners. @@ -94,11 +113,12 @@ import 'runtime.dart'; /// corners and the second the `topEnd` and `bottomEnd`. With three, the /// values are used for `topStart`, `topEnd`-and-`bottomEnd`, and /// `bottomStart` respectively. Four values map to the `topStart`, `topEnd`, -/// `bottomStart`, and `bottomEnd` respectively. +/// `bottomStart`, and `bottomEnd` respectively. See +/// [ArgumentDecoders.borderRadius]. /// /// * [Color] values are represented as integers. The hex literal values are /// most convenient for this, the alpha, red, green, and blue channels map to -/// the 32 bit hex integer as 0xAARRGGBB. +/// the 32 bit hex integer as 0xAARRGGBB. See [ArgumentDecoders.color]. /// /// * [ColorFilter] is represented as a map with a `type` key that matches the /// constructor name (e.g. `linearToSrgbGamma`). The `matrix` version uses @@ -106,14 +126,17 @@ import 'runtime.dart'; /// version expects a `color` key for the color (defaults to black) and a /// `blendMode` key for the blend mode (defaults to [BlendMode.srcOver]). /// Other types are looked up in [ArgumentDecoders.colorFilterDecoders]. +/// See [ArgumentDecoders.colorFilter]. /// /// * [Curve] values are represented as a string giving the kind of curve from /// the predefined [Curves], e.g. `easeInOutCubicEmphasized`. More types may -/// be added using [ArgumentDecoders.curveDecoders]. +/// be added using [ArgumentDecoders.curveDecoders]. See +/// [ArgumentDecoders.curve]. /// /// * The types supported for [Decoration] are `box` for [BoxDecoration], /// `flutterLogo` for [FlutterLogoDecoration], and `shape` for /// [ShapeDecoration]. More types can be added with [decorationDecoders]. +/// See [ArgumentDecoders.decoration]. /// /// * [DecorationImage] expects a `source` key that gives either an absolute /// URL (to use a [NetworkImage]) or the name of an asset in the client @@ -122,15 +145,17 @@ import 'runtime.dart'; /// [DecorationImage.onError] is supported as an event handler with arguments /// giving the stringified exception and stack trace. Values can be added to /// [ArgumentDecoders.imageProviderDecoders] to override the behavior described here. +/// See [ArgumentDecoders.decorationImage]. /// /// * [Duration] is represented by an integer giving milliseconds. +/// See [ArgumentDecoders.duration]. /// /// * [EdgeInsetsGeometry] values work like [BoxBorder], with each value in the -/// array being a double rather than a map. +/// array being a double rather than a map. See [ArgumentDecoders.edgeInsets]. /// /// * [FontFeature] values are a map with a `feature` key and a `value` key. /// The `value` defaults to 1. (Technically the `feature` defaults to `NONE`, -/// too, but that's hardly useful.) +/// too, but that's hardly useful.) See [ArgumentDecoders.fontFeature]. /// /// * The [dart:ui.Gradient] and [painting.Gradient] types are both represented /// as a map with a type that is either `linear` (for [LinearGradient]), @@ -138,12 +163,14 @@ import 'runtime.dart'; /// the conventions from the [painting.Gradient] version. The `transform` /// property on these objects is not currently supported. New gradient types /// can be implemented using [ArgumentDecoders.gradientDecoders]. +/// See [ArgumentDecoders.gradient]. /// /// * The [GridDelegate] type is represented as a map with a `type` key that is /// either `fixedCrossAxisCount` for /// [SliverGridDelegateWithFixedCrossAxisCount] or `maxCrossAxisExtent` for /// [SliverGridDelegateWithMaxCrossAxisExtent]. New delegate types can be /// supported using [ArgumentDecoders.gridDelegateDecoders]. +/// See [ArgumentDecoders.gridDelegate]. /// /// * [IconData] is represented as a map with an `icon` key giving the /// [IconData.codePoint] (and corresponding keys for the other parameters of @@ -152,18 +179,18 @@ import 'runtime.dart'; /// example, [Icons.flutter_dash] is `IconData(0xe2a0, fontFamily: /// 'MaterialIcons')` so it would be represented here as `{ icon: 0xE2A0, /// fontFamily: "MaterialIcons" }`. (The client must have the font as a -/// defined asset.) +/// defined asset.) See [ArgumentDecoders.iconData]. /// /// * [Locale] values are defined as a string in the form `languageCode`, /// `languageCode-countryCode`, or /// `languageCode-scriptCode-countryCode-ignoredSubtags`. The string is split -/// on hyphens. +/// on hyphens. See [ArgumentDecoders.locale]. /// /// * [MaskFilter] is represented as a map with a `type` key that must be /// `blur`; only [MaskFilter.blur] is supported. (The other keys must be -/// `style`, the [BlurStyle], and `sigma`.) +/// `style`, the [BlurStyle], and `sigma`.) See [ArgumentDecoders.maskFilter]. /// -/// * [Offset]s are a map with an `x` key and a `y` key. +/// * [Offset]s are a map with an `x` key and a `y` key. See [ArgumentDecoders.offset]. /// /// * [Paint] objects are represented as maps; each property of [Paint] is a /// key as if there was a constructor that could set all of [Paint]'s @@ -171,13 +198,14 @@ import 'runtime.dart'; /// supported, though since [Paint] is only used as part of /// [painting.TextStyle.background] and [painting.TextStyle.foreground], in /// practice some of the properties are ignored since they would be no-ops -/// (e.g. `invertColors`). +/// (e.g. `invertColors`). See [ArgumentDecoders.paint]. /// /// * [Radius] is represented as a map with an `x` value and optionally a `y` /// value; if the `y` value is absent, the `x` value is used for both. +/// See [ArgumentDecoders.radius]. /// /// * [Rect] values are represented as an array with four doubles, giving the -/// x, y, width, and height respectively. +/// x, y, width, and height respectively. See [ArgumentDecoders.rect]. /// /// * [ShapeBorder] values are represented as either maps with a `type` _or_ as /// an array of [ShapeBorder] values. In the array case, the values are @@ -188,22 +216,25 @@ import 'runtime.dart'; /// `stadium` ([StadiumBorder]). In the case of `box`, there must be a /// `sides` key whose value is an array that is interpreted as per /// [BoxBorder] above. Support for new types can be added using the -/// [ArgumentDecoders.shapeBorderDecoders] map. +/// [ArgumentDecoders.shapeBorderDecoders] map. See +/// [ArgumentDecoders.shapeBorder]. /// /// * [Shader] values are a map with a `type` that is either `linear`, /// `radial`, or `sweep`; in each case, the data is interpreted as per the /// [Gradient] case above, except that the gradient is specifically applied /// to a [Rect] given by the `rect` key and a [TextDirection] given by the /// `textDirection` key. New shader types can be added using -/// [ArgumentDecoders.shaderDecoders]. +/// [ArgumentDecoders.shaderDecoders]. See [ArgumentDecoders.shader]. /// /// * [TextDecoration] is represented either as an array of [TextDecoration] /// values (combined via [TextDecoration.combine]) or a string which matches /// the name of one of the [TextDecoration] constants (e.g. `underline`). +/// See [ArgumentDecoders.textDecoration]. /// /// * [VisualDensity] is either represented as a string which matches one of the /// predefined values (`adaptivePlatformDensity`, `comfortable`, etc), or as /// a map with keys `horizontal` and `vertical` to define a custom density. +/// See [ArgumentDecoders.visualDensity]. /// /// Some of the widgets have special considerations: ///