mirror of
https://github.com/rive-app/rive-flutter
synced 2025-07-05 21:55:58 +00:00
Update flutter runtime
- ran ```dev/generate_core_runtime.sh build``` - cleaned up a lot of accumulated changes from the last few months that needed to be stripped/modified for the rutnime - removed no longer supported lining options from analysis files - fixed up defs for some editor only features so they don't transpile - added some more details to changelog - bumped pubspec version Diffs= aa8c750bd Update flutter runtime (#4835)
This commit is contained in:
@ -1 +1 @@
|
||||
c7d125c7d4efe1233c16c2a95fb7b637b746b010
|
||||
aa8c750bd077f4260c0daf0de988aeae65a07614
|
||||
|
@ -1,6 +1,9 @@
|
||||
## Upcoming
|
||||
## 0.10.2
|
||||
|
||||
- Performance improvement: No longer drawing components with an opacity of 0.
|
||||
- Updated example, see "Skinning Demo".
|
||||
- Support for negative speeds on linear animations when played back in state machines.
|
||||
- Support for overriding speed on animation states.
|
||||
|
||||
## 0.10.1
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
analyzer:
|
||||
strong-mode:
|
||||
implicit-casts: false
|
||||
implicit-dynamic: false
|
||||
errors:
|
||||
unused_import: error
|
||||
exclude:
|
||||
@ -10,116 +7,116 @@ analyzer:
|
||||
|
||||
linter:
|
||||
rules:
|
||||
- always_put_required_named_parameters_first
|
||||
- always_require_non_null_named_parameters
|
||||
- annotate_overrides
|
||||
# - avoid_annotating_with_dynamic
|
||||
- avoid_bool_literals_in_conditional_expressions
|
||||
- avoid_catches_without_on_clauses
|
||||
- avoid_catching_errors
|
||||
- avoid_classes_with_only_static_members
|
||||
- avoid_double_and_int_checks
|
||||
- avoid_empty_else
|
||||
- avoid_field_initializers_in_const_classes
|
||||
- avoid_implementing_value_types
|
||||
- avoid_init_to_null
|
||||
- avoid_js_rounded_ints
|
||||
- avoid_null_checks_in_equality_operators
|
||||
- avoid_relative_lib_imports
|
||||
- avoid_return_types_on_setters
|
||||
- avoid_returning_null
|
||||
- avoid_returning_null_for_future
|
||||
- avoid_returning_null_for_void
|
||||
- avoid_returning_this
|
||||
- avoid_setters_without_getters
|
||||
- avoid_shadowing_type_parameters
|
||||
- avoid_single_cascade_in_expression_statements
|
||||
- avoid_slow_async_io
|
||||
- avoid_types_as_parameter_names
|
||||
- avoid_unused_constructor_parameters
|
||||
- avoid_void_async
|
||||
- await_only_futures
|
||||
- camel_case_types
|
||||
- cancel_subscriptions
|
||||
- close_sinks
|
||||
- constant_identifier_names
|
||||
- control_flow_in_finally
|
||||
- curly_braces_in_flow_control_structures
|
||||
- directives_ordering
|
||||
- empty_catches
|
||||
- empty_constructor_bodies
|
||||
- empty_statements
|
||||
- file_names
|
||||
- hash_and_equals
|
||||
- implementation_imports
|
||||
# - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
|
||||
- iterable_contains_unrelated_type
|
||||
- join_return_with_assignment
|
||||
- library_names
|
||||
- library_prefixes
|
||||
- lines_longer_than_80_chars
|
||||
- list_remove_unrelated_type
|
||||
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
|
||||
- no_adjacent_strings_in_list
|
||||
- no_duplicate_case_values
|
||||
- non_constant_identifier_names
|
||||
- null_closures
|
||||
- one_member_abstracts
|
||||
- only_throw_errors
|
||||
- overridden_fields
|
||||
- package_api_docs
|
||||
- package_names
|
||||
- package_prefixed_library_names
|
||||
- parameter_assignments
|
||||
- prefer_adjacent_string_concatenation
|
||||
- prefer_asserts_in_initializer_lists
|
||||
- prefer_collection_literals
|
||||
- prefer_conditional_assignment
|
||||
- prefer_const_constructors
|
||||
- prefer_const_constructors_in_immutables
|
||||
- prefer_const_declarations
|
||||
- prefer_const_literals_to_create_immutables
|
||||
- prefer_constructors_over_static_methods
|
||||
- prefer_contains
|
||||
- prefer_equal_for_default_values
|
||||
- prefer_final_fields
|
||||
- prefer_final_in_for_each
|
||||
- prefer_foreach
|
||||
- prefer_function_declarations_over_variables
|
||||
- prefer_initializing_formals
|
||||
- prefer_is_empty
|
||||
- prefer_is_not_empty
|
||||
- prefer_iterable_whereType
|
||||
# - prefer_mixin
|
||||
- prefer_null_aware_operators
|
||||
- prefer_typing_uninitialized_variables
|
||||
- prefer_void_to_null
|
||||
- recursive_getters
|
||||
- slash_for_doc_comments
|
||||
- sort_pub_dependencies
|
||||
- sort_unnamed_constructors_first
|
||||
- test_types_in_equals
|
||||
- throw_in_finally
|
||||
- type_annotate_public_apis
|
||||
- type_init_formals
|
||||
- unawaited_futures
|
||||
- unnecessary_await_in_return
|
||||
- unnecessary_brace_in_string_interps
|
||||
- unnecessary_const
|
||||
- unnecessary_getters_setters
|
||||
- unnecessary_lambdas
|
||||
- unnecessary_new
|
||||
- unnecessary_null_aware_assignments
|
||||
- unnecessary_null_in_if_null_operators
|
||||
- unnecessary_overrides
|
||||
- unnecessary_parenthesis
|
||||
- unnecessary_statements
|
||||
- unnecessary_this
|
||||
- unrelated_type_equality_checks
|
||||
- use_full_hex_values_for_flutter_colors
|
||||
- use_rethrow_when_possible
|
||||
- use_setters_to_change_properties
|
||||
- use_string_buffers
|
||||
- use_to_and_as_if_applicable
|
||||
- valid_regexps
|
||||
- void_checks
|
||||
- always_put_required_named_parameters_first
|
||||
- always_require_non_null_named_parameters
|
||||
- annotate_overrides
|
||||
# - avoid_annotating_with_dynamic
|
||||
- avoid_bool_literals_in_conditional_expressions
|
||||
- avoid_catches_without_on_clauses
|
||||
- avoid_catching_errors
|
||||
- avoid_classes_with_only_static_members
|
||||
- avoid_double_and_int_checks
|
||||
- avoid_empty_else
|
||||
- avoid_field_initializers_in_const_classes
|
||||
- avoid_implementing_value_types
|
||||
- avoid_init_to_null
|
||||
- avoid_js_rounded_ints
|
||||
- avoid_null_checks_in_equality_operators
|
||||
- avoid_relative_lib_imports
|
||||
- avoid_return_types_on_setters
|
||||
- avoid_returning_null
|
||||
- avoid_returning_null_for_future
|
||||
- avoid_returning_null_for_void
|
||||
- avoid_returning_this
|
||||
- avoid_setters_without_getters
|
||||
- avoid_shadowing_type_parameters
|
||||
- avoid_single_cascade_in_expression_statements
|
||||
- avoid_slow_async_io
|
||||
- avoid_types_as_parameter_names
|
||||
- avoid_unused_constructor_parameters
|
||||
- avoid_void_async
|
||||
- await_only_futures
|
||||
- camel_case_types
|
||||
- cancel_subscriptions
|
||||
- close_sinks
|
||||
- constant_identifier_names
|
||||
- control_flow_in_finally
|
||||
- curly_braces_in_flow_control_structures
|
||||
- directives_ordering
|
||||
- empty_catches
|
||||
- empty_constructor_bodies
|
||||
- empty_statements
|
||||
- file_names
|
||||
- hash_and_equals
|
||||
- implementation_imports
|
||||
# - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
|
||||
- iterable_contains_unrelated_type
|
||||
- join_return_with_assignment
|
||||
- library_names
|
||||
- library_prefixes
|
||||
- lines_longer_than_80_chars
|
||||
- list_remove_unrelated_type
|
||||
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
|
||||
- no_adjacent_strings_in_list
|
||||
- no_duplicate_case_values
|
||||
- non_constant_identifier_names
|
||||
- null_closures
|
||||
- one_member_abstracts
|
||||
- only_throw_errors
|
||||
- overridden_fields
|
||||
- package_api_docs
|
||||
- package_names
|
||||
- package_prefixed_library_names
|
||||
- parameter_assignments
|
||||
- prefer_adjacent_string_concatenation
|
||||
- prefer_asserts_in_initializer_lists
|
||||
- prefer_collection_literals
|
||||
- prefer_conditional_assignment
|
||||
- prefer_const_constructors
|
||||
- prefer_const_constructors_in_immutables
|
||||
- prefer_const_declarations
|
||||
- prefer_const_literals_to_create_immutables
|
||||
- prefer_constructors_over_static_methods
|
||||
- prefer_contains
|
||||
- prefer_equal_for_default_values
|
||||
- prefer_final_fields
|
||||
- prefer_final_in_for_each
|
||||
- prefer_foreach
|
||||
- prefer_function_declarations_over_variables
|
||||
- prefer_initializing_formals
|
||||
- prefer_is_empty
|
||||
- prefer_is_not_empty
|
||||
- prefer_iterable_whereType
|
||||
# - prefer_mixin
|
||||
- prefer_null_aware_operators
|
||||
- prefer_typing_uninitialized_variables
|
||||
- prefer_void_to_null
|
||||
- recursive_getters
|
||||
- slash_for_doc_comments
|
||||
- sort_pub_dependencies
|
||||
- sort_unnamed_constructors_first
|
||||
- test_types_in_equals
|
||||
- throw_in_finally
|
||||
- type_annotate_public_apis
|
||||
- type_init_formals
|
||||
- unawaited_futures
|
||||
- unnecessary_await_in_return
|
||||
- unnecessary_brace_in_string_interps
|
||||
- unnecessary_const
|
||||
- unnecessary_getters_setters
|
||||
- unnecessary_lambdas
|
||||
- unnecessary_new
|
||||
- unnecessary_null_aware_assignments
|
||||
- unnecessary_null_in_if_null_operators
|
||||
- unnecessary_overrides
|
||||
- unnecessary_parenthesis
|
||||
- unnecessary_statements
|
||||
- unnecessary_this
|
||||
- unrelated_type_equality_checks
|
||||
- use_full_hex_values_for_flutter_colors
|
||||
- use_rethrow_when_possible
|
||||
- use_setters_to_change_properties
|
||||
- use_string_buffers
|
||||
- use_to_and_as_if_applicable
|
||||
- valid_regexps
|
||||
- void_checks
|
||||
|
@ -14,8 +14,8 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/rive_common/macos
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811
|
||||
rive_common: 0ac58617cab300ee9bcf495e710d593578ff328b
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
rive_common: 643f5c20ccd60c53136ab5c970eccf0d17e010fe
|
||||
|
||||
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
|
||||
|
||||
|
41
lib/src/generated/animation/keyframe_string_base.dart
Normal file
41
lib/src/generated/animation/keyframe_string_base.dart
Normal file
@ -0,0 +1,41 @@
|
||||
/// Core automatically generated
|
||||
/// lib/src/generated/animation/keyframe_string_base.dart.
|
||||
/// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/rive_core/animation/keyframe.dart';
|
||||
|
||||
abstract class KeyFrameStringBase extends KeyFrame {
|
||||
static const int typeKey = 142;
|
||||
@override
|
||||
int get coreType => KeyFrameStringBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes => {KeyFrameStringBase.typeKey, KeyFrameBase.typeKey};
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Value field with key 280.
|
||||
static const String valueInitialValue = '';
|
||||
String _value = valueInitialValue;
|
||||
static const int valuePropertyKey = 280;
|
||||
String get value => _value;
|
||||
|
||||
/// Change the [_value] field value.
|
||||
/// [valueChanged] will be invoked only if the field's value has changed.
|
||||
set value(String value) {
|
||||
if (_value == value) {
|
||||
return;
|
||||
}
|
||||
String from = _value;
|
||||
_value = value;
|
||||
if (hasValidated) {
|
||||
valueChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void valueChanged(String from, String to);
|
||||
|
||||
@override
|
||||
void copy(covariant KeyFrameStringBase source) {
|
||||
super.copy(source);
|
||||
_value = source._value;
|
||||
}
|
||||
}
|
14
lib/src/generated/assets/font_asset_base.dart
Normal file
14
lib/src/generated/assets/font_asset_base.dart
Normal file
@ -0,0 +1,14 @@
|
||||
/// Core automatically generated lib/src/generated/assets/font_asset_base.dart.
|
||||
/// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/generated/assets/asset_base.dart';
|
||||
import 'package:rive/src/rive_core/assets/file_asset.dart';
|
||||
|
||||
abstract class FontAssetBase extends FileAsset {
|
||||
static const int typeKey = 141;
|
||||
@override
|
||||
int get coreType => FontAssetBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes =>
|
||||
{FontAssetBase.typeKey, FileAssetBase.typeKey, AssetBase.typeKey};
|
||||
}
|
@ -10,6 +10,7 @@ import 'package:rive/src/generated/animation/blend_animation_base.dart';
|
||||
import 'package:rive/src/generated/animation/cubic_ease_interpolator_base.dart';
|
||||
import 'package:rive/src/generated/animation/cubic_interpolator_base.dart';
|
||||
import 'package:rive/src/generated/animation/keyframe_base.dart';
|
||||
import 'package:rive/src/generated/animation/keyframe_string_base.dart';
|
||||
import 'package:rive/src/generated/animation/listener_input_change_base.dart';
|
||||
import 'package:rive/src/generated/animation/nested_input_base.dart';
|
||||
import 'package:rive/src/generated/animation/nested_linear_animation_base.dart';
|
||||
@ -51,6 +52,7 @@ import 'package:rive/src/rive_core/animation/keyframe_bool.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyframe_color.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyframe_double.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyframe_id.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyframe_string.dart';
|
||||
import 'package:rive/src/rive_core/animation/linear_animation.dart';
|
||||
import 'package:rive/src/rive_core/animation/listener_align_target.dart';
|
||||
import 'package:rive/src/rive_core/animation/listener_bool_change.dart';
|
||||
@ -75,6 +77,7 @@ import 'package:rive/src/rive_core/animation/transition_trigger_condition.dart';
|
||||
import 'package:rive/src/rive_core/artboard.dart';
|
||||
import 'package:rive/src/rive_core/assets/file_asset_contents.dart';
|
||||
import 'package:rive/src/rive_core/assets/folder.dart';
|
||||
import 'package:rive/src/rive_core/assets/font_asset.dart';
|
||||
import 'package:rive/src/rive_core/assets/image_asset.dart';
|
||||
import 'package:rive/src/rive_core/backboard.dart';
|
||||
import 'package:rive/src/rive_core/bones/bone.dart';
|
||||
@ -94,7 +97,6 @@ import 'package:rive/src/rive_core/custom_property_number.dart';
|
||||
import 'package:rive/src/rive_core/custom_property_string.dart';
|
||||
import 'package:rive/src/rive_core/draw_rules.dart';
|
||||
import 'package:rive/src/rive_core/draw_target.dart';
|
||||
import 'package:rive/src/rive_core/event.dart';
|
||||
import 'package:rive/src/rive_core/nested_artboard.dart';
|
||||
import 'package:rive/src/rive_core/node.dart';
|
||||
import 'package:rive/src/rive_core/shapes/clipping_shape.dart';
|
||||
@ -120,6 +122,10 @@ import 'package:rive/src/rive_core/shapes/shape.dart';
|
||||
import 'package:rive/src/rive_core/shapes/star.dart';
|
||||
import 'package:rive/src/rive_core/shapes/straight_vertex.dart';
|
||||
import 'package:rive/src/rive_core/shapes/triangle.dart';
|
||||
import 'package:rive/src/rive_core/text/text.dart';
|
||||
import 'package:rive/src/rive_core/text/text_style.dart';
|
||||
import 'package:rive/src/rive_core/text/text_style_axis.dart';
|
||||
import 'package:rive/src/rive_core/text/text_value_run.dart';
|
||||
|
||||
// ignore: avoid_classes_with_only_static_members
|
||||
class RiveCoreContext {
|
||||
@ -183,6 +189,8 @@ class RiveCoreContext {
|
||||
return AnyState();
|
||||
case StateMachineLayerBase.typeKey:
|
||||
return StateMachineLayer();
|
||||
case KeyFrameStringBase.typeKey:
|
||||
return KeyFrameString();
|
||||
case ListenerNumberChangeBase.typeKey:
|
||||
return ListenerNumberChange();
|
||||
case CubicEaseInterpolatorBase.typeKey:
|
||||
@ -273,8 +281,6 @@ class RiveCoreContext {
|
||||
return Image();
|
||||
case CubicDetachedVertexBase.typeKey:
|
||||
return CubicDetachedVertex();
|
||||
case EventBase.typeKey:
|
||||
return Event();
|
||||
case DrawRulesBase.typeKey:
|
||||
return DrawRules();
|
||||
case CustomPropertyBooleanBase.typeKey:
|
||||
@ -291,12 +297,22 @@ class RiveCoreContext {
|
||||
return Skin();
|
||||
case TendonBase.typeKey:
|
||||
return Tendon();
|
||||
case TextStyleBase.typeKey:
|
||||
return TextStyle();
|
||||
case TextStyleAxisBase.typeKey:
|
||||
return TextStyleAxis();
|
||||
case TextBase.typeKey:
|
||||
return Text();
|
||||
case TextValueRunBase.typeKey:
|
||||
return TextValueRun();
|
||||
case CustomPropertyStringBase.typeKey:
|
||||
return CustomPropertyString();
|
||||
case FolderBase.typeKey:
|
||||
return Folder();
|
||||
case ImageAssetBase.typeKey:
|
||||
return ImageAsset();
|
||||
case FontAssetBase.typeKey:
|
||||
return FontAsset();
|
||||
case FileAssetContentsBase.typeKey:
|
||||
return FileAssetContents();
|
||||
default:
|
||||
@ -671,6 +687,11 @@ class RiveCoreContext {
|
||||
object.value = value;
|
||||
}
|
||||
break;
|
||||
case KeyFrameStringBase.valuePropertyKey:
|
||||
if (object is KeyFrameStringBase && value is String) {
|
||||
object.value = value;
|
||||
}
|
||||
break;
|
||||
case ListenerNumberChangeBase.valuePropertyKey:
|
||||
if (object is ListenerNumberChangeBase && value is double) {
|
||||
object.value = value;
|
||||
@ -1026,11 +1047,6 @@ class RiveCoreContext {
|
||||
object.outDistance = value;
|
||||
}
|
||||
break;
|
||||
case EventBase.typePropertyKey:
|
||||
if (object is EventBase && value is String) {
|
||||
object.type = value;
|
||||
}
|
||||
break;
|
||||
case DrawRulesBase.drawTargetIdPropertyKey:
|
||||
if (object is DrawRulesBase && value is int) {
|
||||
object.drawTargetId = value;
|
||||
@ -1161,6 +1177,61 @@ class RiveCoreContext {
|
||||
object.ty = value;
|
||||
}
|
||||
break;
|
||||
case TextStyleBase.fontSizePropertyKey:
|
||||
if (object is TextStyleBase && value is double) {
|
||||
object.fontSize = value;
|
||||
}
|
||||
break;
|
||||
case TextStyleBase.fontAssetIdPropertyKey:
|
||||
if (object is TextStyleBase && value is int) {
|
||||
object.fontAssetId = value;
|
||||
}
|
||||
break;
|
||||
case TextStyleAxisBase.tagPropertyKey:
|
||||
if (object is TextStyleAxisBase && value is int) {
|
||||
object.tag = value;
|
||||
}
|
||||
break;
|
||||
case TextStyleAxisBase.axisValuePropertyKey:
|
||||
if (object is TextStyleAxisBase && value is double) {
|
||||
object.axisValue = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.alignValuePropertyKey:
|
||||
if (object is TextBase && value is int) {
|
||||
object.alignValue = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.sizingValuePropertyKey:
|
||||
if (object is TextBase && value is int) {
|
||||
object.sizingValue = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.overflowValuePropertyKey:
|
||||
if (object is TextBase && value is int) {
|
||||
object.overflowValue = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.widthPropertyKey:
|
||||
if (object is TextBase && value is double) {
|
||||
object.width = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.heightPropertyKey:
|
||||
if (object is TextBase && value is double) {
|
||||
object.height = value;
|
||||
}
|
||||
break;
|
||||
case TextValueRunBase.styleIdPropertyKey:
|
||||
if (object is TextValueRunBase && value is int) {
|
||||
object.styleId = value;
|
||||
}
|
||||
break;
|
||||
case TextValueRunBase.textPropertyKey:
|
||||
if (object is TextValueRunBase && value is String) {
|
||||
object.text = value;
|
||||
}
|
||||
break;
|
||||
case CustomPropertyStringBase.propertyValuePropertyKey:
|
||||
if (object is CustomPropertyStringBase && value is String) {
|
||||
object.propertyValue = value;
|
||||
@ -1205,7 +1276,8 @@ class RiveCoreContext {
|
||||
case ComponentBase.namePropertyKey:
|
||||
case AnimationBase.namePropertyKey:
|
||||
case StateMachineComponentBase.namePropertyKey:
|
||||
case EventBase.typePropertyKey:
|
||||
case KeyFrameStringBase.valuePropertyKey:
|
||||
case TextValueRunBase.textPropertyKey:
|
||||
case CustomPropertyStringBase.propertyValuePropertyKey:
|
||||
case AssetBase.namePropertyKey:
|
||||
return stringType;
|
||||
@ -1268,6 +1340,12 @@ class RiveCoreContext {
|
||||
case DrawRulesBase.drawTargetIdPropertyKey:
|
||||
case ArtboardBase.defaultStateMachineIdPropertyKey:
|
||||
case TendonBase.boneIdPropertyKey:
|
||||
case TextStyleBase.fontAssetIdPropertyKey:
|
||||
case TextStyleAxisBase.tagPropertyKey:
|
||||
case TextBase.alignValuePropertyKey:
|
||||
case TextBase.sizingValuePropertyKey:
|
||||
case TextBase.overflowValuePropertyKey:
|
||||
case TextValueRunBase.styleIdPropertyKey:
|
||||
case FileAssetBase.assetIdPropertyKey:
|
||||
return uintType;
|
||||
case CustomPropertyNumberBase.propertyValuePropertyKey:
|
||||
@ -1354,6 +1432,10 @@ class RiveCoreContext {
|
||||
case TendonBase.yyPropertyKey:
|
||||
case TendonBase.txPropertyKey:
|
||||
case TendonBase.tyPropertyKey:
|
||||
case TextStyleBase.fontSizePropertyKey:
|
||||
case TextStyleAxisBase.axisValuePropertyKey:
|
||||
case TextBase.widthPropertyKey:
|
||||
case TextBase.heightPropertyKey:
|
||||
case DrawableAssetBase.heightPropertyKey:
|
||||
case DrawableAssetBase.widthPropertyKey:
|
||||
return doubleType;
|
||||
@ -1398,8 +1480,10 @@ class RiveCoreContext {
|
||||
return (object as AnimationBase).name;
|
||||
case StateMachineComponentBase.namePropertyKey:
|
||||
return (object as StateMachineComponentBase).name;
|
||||
case EventBase.typePropertyKey:
|
||||
return (object as EventBase).type;
|
||||
case KeyFrameStringBase.valuePropertyKey:
|
||||
return (object as KeyFrameStringBase).value;
|
||||
case TextValueRunBase.textPropertyKey:
|
||||
return (object as TextValueRunBase).text;
|
||||
case CustomPropertyStringBase.propertyValuePropertyKey:
|
||||
return (object as CustomPropertyStringBase).propertyValue;
|
||||
case AssetBase.namePropertyKey:
|
||||
@ -1528,6 +1612,18 @@ class RiveCoreContext {
|
||||
return (object as ArtboardBase).defaultStateMachineId;
|
||||
case TendonBase.boneIdPropertyKey:
|
||||
return (object as TendonBase).boneId;
|
||||
case TextStyleBase.fontAssetIdPropertyKey:
|
||||
return (object as TextStyleBase).fontAssetId;
|
||||
case TextStyleAxisBase.tagPropertyKey:
|
||||
return (object as TextStyleAxisBase).tag;
|
||||
case TextBase.alignValuePropertyKey:
|
||||
return (object as TextBase).alignValue;
|
||||
case TextBase.sizingValuePropertyKey:
|
||||
return (object as TextBase).sizingValue;
|
||||
case TextBase.overflowValuePropertyKey:
|
||||
return (object as TextBase).overflowValue;
|
||||
case TextValueRunBase.styleIdPropertyKey:
|
||||
return (object as TextValueRunBase).styleId;
|
||||
case FileAssetBase.assetIdPropertyKey:
|
||||
return (object as FileAssetBase).assetId;
|
||||
}
|
||||
@ -1704,6 +1800,14 @@ class RiveCoreContext {
|
||||
return (object as TendonBase).tx;
|
||||
case TendonBase.tyPropertyKey:
|
||||
return (object as TendonBase).ty;
|
||||
case TextStyleBase.fontSizePropertyKey:
|
||||
return (object as TextStyleBase).fontSize;
|
||||
case TextStyleAxisBase.axisValuePropertyKey:
|
||||
return (object as TextStyleAxisBase).axisValue;
|
||||
case TextBase.widthPropertyKey:
|
||||
return (object as TextBase).width;
|
||||
case TextBase.heightPropertyKey:
|
||||
return (object as TextBase).height;
|
||||
case DrawableAssetBase.heightPropertyKey:
|
||||
return (object as DrawableAssetBase).height;
|
||||
case DrawableAssetBase.widthPropertyKey:
|
||||
@ -1797,9 +1901,14 @@ class RiveCoreContext {
|
||||
object.name = value;
|
||||
}
|
||||
break;
|
||||
case EventBase.typePropertyKey:
|
||||
if (object is EventBase) {
|
||||
object.type = value;
|
||||
case KeyFrameStringBase.valuePropertyKey:
|
||||
if (object is KeyFrameStringBase) {
|
||||
object.value = value;
|
||||
}
|
||||
break;
|
||||
case TextValueRunBase.textPropertyKey:
|
||||
if (object is TextValueRunBase) {
|
||||
object.text = value;
|
||||
}
|
||||
break;
|
||||
case CustomPropertyStringBase.propertyValuePropertyKey:
|
||||
@ -2112,6 +2221,36 @@ class RiveCoreContext {
|
||||
object.boneId = value;
|
||||
}
|
||||
break;
|
||||
case TextStyleBase.fontAssetIdPropertyKey:
|
||||
if (object is TextStyleBase) {
|
||||
object.fontAssetId = value;
|
||||
}
|
||||
break;
|
||||
case TextStyleAxisBase.tagPropertyKey:
|
||||
if (object is TextStyleAxisBase) {
|
||||
object.tag = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.alignValuePropertyKey:
|
||||
if (object is TextBase) {
|
||||
object.alignValue = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.sizingValuePropertyKey:
|
||||
if (object is TextBase) {
|
||||
object.sizingValue = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.overflowValuePropertyKey:
|
||||
if (object is TextBase) {
|
||||
object.overflowValue = value;
|
||||
}
|
||||
break;
|
||||
case TextValueRunBase.styleIdPropertyKey:
|
||||
if (object is TextValueRunBase) {
|
||||
object.styleId = value;
|
||||
}
|
||||
break;
|
||||
case FileAssetBase.assetIdPropertyKey:
|
||||
if (object is FileAssetBase) {
|
||||
object.assetId = value;
|
||||
@ -2542,6 +2681,26 @@ class RiveCoreContext {
|
||||
object.ty = value;
|
||||
}
|
||||
break;
|
||||
case TextStyleBase.fontSizePropertyKey:
|
||||
if (object is TextStyleBase) {
|
||||
object.fontSize = value;
|
||||
}
|
||||
break;
|
||||
case TextStyleAxisBase.axisValuePropertyKey:
|
||||
if (object is TextStyleAxisBase) {
|
||||
object.axisValue = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.widthPropertyKey:
|
||||
if (object is TextBase) {
|
||||
object.width = value;
|
||||
}
|
||||
break;
|
||||
case TextBase.heightPropertyKey:
|
||||
if (object is TextBase) {
|
||||
object.height = value;
|
||||
}
|
||||
break;
|
||||
case DrawableAssetBase.heightPropertyKey:
|
||||
if (object is DrawableAssetBase) {
|
||||
object.height = value;
|
||||
|
@ -1,7 +1,6 @@
|
||||
/// Core automatically generated lib/src/generated/shapes/mesh_base.dart.
|
||||
/// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/component_base.dart';
|
||||
import 'package:rive/src/generated/container_component_base.dart';
|
||||
import 'package:rive/src/rive_core/container_component.dart';
|
||||
|
153
lib/src/generated/text/text_base.dart
Normal file
153
lib/src/generated/text/text_base.dart
Normal file
@ -0,0 +1,153 @@
|
||||
/// Core automatically generated lib/src/generated/text/text_base.dart.
|
||||
/// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/generated/component_base.dart';
|
||||
import 'package:rive/src/generated/container_component_base.dart';
|
||||
import 'package:rive/src/generated/node_base.dart';
|
||||
import 'package:rive/src/generated/transform_component_base.dart';
|
||||
import 'package:rive/src/generated/world_transform_component_base.dart';
|
||||
import 'package:rive/src/rive_core/drawable.dart';
|
||||
|
||||
abstract class TextBase extends Drawable {
|
||||
static const int typeKey = 134;
|
||||
@override
|
||||
int get coreType => TextBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes => {
|
||||
TextBase.typeKey,
|
||||
DrawableBase.typeKey,
|
||||
NodeBase.typeKey,
|
||||
TransformComponentBase.typeKey,
|
||||
WorldTransformComponentBase.typeKey,
|
||||
ContainerComponentBase.typeKey,
|
||||
ComponentBase.typeKey
|
||||
};
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// AlignValue field with key 281.
|
||||
static const int alignValueInitialValue = 0;
|
||||
int _alignValue = alignValueInitialValue;
|
||||
static const int alignValuePropertyKey = 281;
|
||||
int get alignValue => _alignValue;
|
||||
|
||||
/// Change the [_alignValue] field value.
|
||||
/// [alignValueChanged] will be invoked only if the field's value has changed.
|
||||
set alignValue(int value) {
|
||||
if (_alignValue == value) {
|
||||
return;
|
||||
}
|
||||
int from = _alignValue;
|
||||
_alignValue = value;
|
||||
if (hasValidated) {
|
||||
alignValueChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void alignValueChanged(int from, int to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// SizingValue field with key 284.
|
||||
static const int sizingValueInitialValue = 0;
|
||||
int _sizingValue = sizingValueInitialValue;
|
||||
static const int sizingValuePropertyKey = 284;
|
||||
int get sizingValue => _sizingValue;
|
||||
|
||||
/// Change the [_sizingValue] field value.
|
||||
/// [sizingValueChanged] will be invoked only if the field's value has
|
||||
/// changed.
|
||||
set sizingValue(int value) {
|
||||
if (_sizingValue == value) {
|
||||
return;
|
||||
}
|
||||
int from = _sizingValue;
|
||||
_sizingValue = value;
|
||||
if (hasValidated) {
|
||||
sizingValueChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void sizingValueChanged(int from, int to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// OverflowValue field with key 287.
|
||||
static const int overflowValueInitialValue = 0;
|
||||
int _overflowValue = overflowValueInitialValue;
|
||||
static const int overflowValuePropertyKey = 287;
|
||||
|
||||
/// One of visible, hidden, clipped, ellipsis.
|
||||
int get overflowValue => _overflowValue;
|
||||
|
||||
/// Change the [_overflowValue] field value.
|
||||
/// [overflowValueChanged] will be invoked only if the field's value has
|
||||
/// changed.
|
||||
set overflowValue(int value) {
|
||||
if (_overflowValue == value) {
|
||||
return;
|
||||
}
|
||||
int from = _overflowValue;
|
||||
_overflowValue = value;
|
||||
if (hasValidated) {
|
||||
overflowValueChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void overflowValueChanged(int from, int to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Width field with key 285.
|
||||
static const double widthInitialValue = 0;
|
||||
double _width = widthInitialValue;
|
||||
static const int widthPropertyKey = 285;
|
||||
|
||||
/// Width of the text object.
|
||||
double get width => _width;
|
||||
|
||||
/// Change the [_width] field value.
|
||||
/// [widthChanged] will be invoked only if the field's value has changed.
|
||||
set width(double value) {
|
||||
if (_width == value) {
|
||||
return;
|
||||
}
|
||||
double from = _width;
|
||||
_width = value;
|
||||
if (hasValidated) {
|
||||
widthChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void widthChanged(double from, double to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Height field with key 286.
|
||||
static const double heightInitialValue = 0;
|
||||
double _height = heightInitialValue;
|
||||
static const int heightPropertyKey = 286;
|
||||
|
||||
/// Height of the text object.
|
||||
double get height => _height;
|
||||
|
||||
/// Change the [_height] field value.
|
||||
/// [heightChanged] will be invoked only if the field's value has changed.
|
||||
set height(double value) {
|
||||
if (_height == value) {
|
||||
return;
|
||||
}
|
||||
double from = _height;
|
||||
_height = value;
|
||||
if (hasValidated) {
|
||||
heightChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void heightChanged(double from, double to);
|
||||
|
||||
@override
|
||||
void copy(covariant TextBase source) {
|
||||
super.copy(source);
|
||||
_alignValue = source._alignValue;
|
||||
_sizingValue = source._sizingValue;
|
||||
_overflowValue = source._overflowValue;
|
||||
_width = source._width;
|
||||
_height = source._height;
|
||||
}
|
||||
}
|
64
lib/src/generated/text/text_style_axis_base.dart
Normal file
64
lib/src/generated/text/text_style_axis_base.dart
Normal file
@ -0,0 +1,64 @@
|
||||
/// Core automatically generated
|
||||
/// lib/src/generated/text/text_style_axis_base.dart.
|
||||
/// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
|
||||
abstract class TextStyleAxisBase extends Component {
|
||||
static const int typeKey = 144;
|
||||
@override
|
||||
int get coreType => TextStyleAxisBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes => {TextStyleAxisBase.typeKey, ComponentBase.typeKey};
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Tag field with key 289.
|
||||
static const int tagInitialValue = 0;
|
||||
int _tag = tagInitialValue;
|
||||
static const int tagPropertyKey = 289;
|
||||
int get tag => _tag;
|
||||
|
||||
/// Change the [_tag] field value.
|
||||
/// [tagChanged] will be invoked only if the field's value has changed.
|
||||
set tag(int value) {
|
||||
if (_tag == value) {
|
||||
return;
|
||||
}
|
||||
int from = _tag;
|
||||
_tag = value;
|
||||
if (hasValidated) {
|
||||
tagChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void tagChanged(int from, int to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// AxisValue field with key 288.
|
||||
static const double axisValueInitialValue = 0;
|
||||
double _axisValue = axisValueInitialValue;
|
||||
static const int axisValuePropertyKey = 288;
|
||||
double get axisValue => _axisValue;
|
||||
|
||||
/// Change the [_axisValue] field value.
|
||||
/// [axisValueChanged] will be invoked only if the field's value has changed.
|
||||
set axisValue(double value) {
|
||||
if (_axisValue == value) {
|
||||
return;
|
||||
}
|
||||
double from = _axisValue;
|
||||
_axisValue = value;
|
||||
if (hasValidated) {
|
||||
axisValueChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void axisValueChanged(double from, double to);
|
||||
|
||||
@override
|
||||
void copy(covariant TextStyleAxisBase source) {
|
||||
super.copy(source);
|
||||
_tag = source._tag;
|
||||
_axisValue = source._axisValue;
|
||||
}
|
||||
}
|
70
lib/src/generated/text/text_style_base.dart
Normal file
70
lib/src/generated/text/text_style_base.dart
Normal file
@ -0,0 +1,70 @@
|
||||
/// Core automatically generated lib/src/generated/text/text_style_base.dart.
|
||||
/// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/generated/component_base.dart';
|
||||
import 'package:rive/src/generated/container_component_base.dart';
|
||||
import 'package:rive/src/rive_core/container_component.dart';
|
||||
|
||||
abstract class TextStyleBase extends ContainerComponent {
|
||||
static const int typeKey = 137;
|
||||
@override
|
||||
int get coreType => TextStyleBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes => {
|
||||
TextStyleBase.typeKey,
|
||||
ContainerComponentBase.typeKey,
|
||||
ComponentBase.typeKey
|
||||
};
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// FontSize field with key 274.
|
||||
static const double fontSizeInitialValue = 12;
|
||||
double _fontSize = fontSizeInitialValue;
|
||||
static const int fontSizePropertyKey = 274;
|
||||
double get fontSize => _fontSize;
|
||||
|
||||
/// Change the [_fontSize] field value.
|
||||
/// [fontSizeChanged] will be invoked only if the field's value has changed.
|
||||
set fontSize(double value) {
|
||||
if (_fontSize == value) {
|
||||
return;
|
||||
}
|
||||
double from = _fontSize;
|
||||
_fontSize = value;
|
||||
if (hasValidated) {
|
||||
fontSizeChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void fontSizeChanged(double from, double to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// FontAssetId field with key 279.
|
||||
static const int fontAssetIdInitialValue = -1;
|
||||
int _fontAssetId = fontAssetIdInitialValue;
|
||||
static const int fontAssetIdPropertyKey = 279;
|
||||
int get fontAssetId => _fontAssetId;
|
||||
|
||||
/// Change the [_fontAssetId] field value.
|
||||
/// [fontAssetIdChanged] will be invoked only if the field's value has
|
||||
/// changed.
|
||||
set fontAssetId(int value) {
|
||||
if (_fontAssetId == value) {
|
||||
return;
|
||||
}
|
||||
int from = _fontAssetId;
|
||||
_fontAssetId = value;
|
||||
if (hasValidated) {
|
||||
fontAssetIdChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void fontAssetIdChanged(int from, int to);
|
||||
|
||||
@override
|
||||
void copy(covariant TextStyleBase source) {
|
||||
super.copy(source);
|
||||
_fontSize = source._fontSize;
|
||||
_fontAssetId = source._fontAssetId;
|
||||
}
|
||||
}
|
68
lib/src/generated/text/text_value_run_base.dart
Normal file
68
lib/src/generated/text/text_value_run_base.dart
Normal file
@ -0,0 +1,68 @@
|
||||
/// Core automatically generated
|
||||
/// lib/src/generated/text/text_value_run_base.dart.
|
||||
/// Do not modify manually.
|
||||
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
|
||||
abstract class TextValueRunBase extends Component {
|
||||
static const int typeKey = 135;
|
||||
@override
|
||||
int get coreType => TextValueRunBase.typeKey;
|
||||
@override
|
||||
Set<int> get coreTypes => {TextValueRunBase.typeKey, ComponentBase.typeKey};
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// StyleId field with key 272.
|
||||
static const int styleIdInitialValue = -1;
|
||||
int _styleId = styleIdInitialValue;
|
||||
static const int styleIdPropertyKey = 272;
|
||||
|
||||
/// The id of the style to be applied to this run.
|
||||
int get styleId => _styleId;
|
||||
|
||||
/// Change the [_styleId] field value.
|
||||
/// [styleIdChanged] will be invoked only if the field's value has changed.
|
||||
set styleId(int value) {
|
||||
if (_styleId == value) {
|
||||
return;
|
||||
}
|
||||
int from = _styleId;
|
||||
_styleId = value;
|
||||
if (hasValidated) {
|
||||
styleIdChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void styleIdChanged(int from, int to);
|
||||
|
||||
/// --------------------------------------------------------------------------
|
||||
/// Text field with key 268.
|
||||
static const String textInitialValue = '';
|
||||
String _text = textInitialValue;
|
||||
static const int textPropertyKey = 268;
|
||||
|
||||
/// The text string value.
|
||||
String get text => _text;
|
||||
|
||||
/// Change the [_text] field value.
|
||||
/// [textChanged] will be invoked only if the field's value has changed.
|
||||
set text(String value) {
|
||||
if (_text == value) {
|
||||
return;
|
||||
}
|
||||
String from = _text;
|
||||
_text = value;
|
||||
if (hasValidated) {
|
||||
textChanged(from, value);
|
||||
}
|
||||
}
|
||||
|
||||
void textChanged(String from, String to);
|
||||
|
||||
@override
|
||||
void copy(covariant TextValueRunBase source) {
|
||||
super.copy(source);
|
||||
_styleId = source._styleId;
|
||||
_text = source._text;
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@ abstract class BlendAnimation extends BlendAnimationBase {
|
||||
@override
|
||||
void onAdded() {}
|
||||
|
||||
|
||||
@override
|
||||
void onAddedDirty() {}
|
||||
|
||||
|
@ -20,7 +20,6 @@ class KeyedObject extends KeyedObjectBase<RuntimeArtboard> {
|
||||
@override
|
||||
void onAdded() {}
|
||||
|
||||
|
||||
bool isValidKeyedProperty(KeyedProperty property) {
|
||||
var value = _keyedProperties[property.propertyKey];
|
||||
|
||||
|
@ -62,7 +62,6 @@ class KeyedProperty extends KeyedPropertyBase<RuntimeArtboard>
|
||||
@override
|
||||
void onAddedDirty() {}
|
||||
|
||||
|
||||
/// Called by rive_core to add a KeyFrame to this KeyedProperty. This should
|
||||
/// be @internal when it's supported.
|
||||
bool internalAddKeyFrame(KeyFrame frame) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/animation/keyframe_base.dart';
|
||||
import 'package:rive/src/rive_core/animation/cubic_interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/cubic_value_interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/interpolator.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyed_property.dart';
|
||||
import 'package:rive/src/rive_core/animation/keyframe_interpolation.dart';
|
||||
@ -42,8 +44,27 @@ abstract class KeyFrame extends KeyFrameBase<RuntimeArtboard>
|
||||
if (interpolatorId != Core.missingId) {
|
||||
interpolator = context.resolve(interpolatorId);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure interpolation types are valid, correct them if not.
|
||||
switch (interpolation) {
|
||||
case KeyFrameInterpolation.cubicValue:
|
||||
if (interpolator is! CubicValueInterpolator) {
|
||||
interpolation = canInterpolate
|
||||
? KeyFrameInterpolation.linear
|
||||
: KeyFrameInterpolation.hold;
|
||||
}
|
||||
break;
|
||||
case KeyFrameInterpolation.cubic:
|
||||
if (interpolator is! CubicInterpolator) {
|
||||
interpolation = canInterpolate
|
||||
? KeyFrameInterpolation.linear
|
||||
: KeyFrameInterpolation.hold;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void frameChanged(int from, int to) {}
|
||||
|
22
lib/src/rive_core/animation/keyframe_string.dart
Normal file
22
lib/src/rive_core/animation/keyframe_string.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/animation/keyframe_string_base.dart';
|
||||
export 'package:rive/src/generated/animation/keyframe_id_base.dart';
|
||||
|
||||
class KeyFrameString extends KeyFrameStringBase {
|
||||
@override
|
||||
bool get canInterpolate => false;
|
||||
|
||||
@override
|
||||
void apply(Core<CoreContext> object, int propertyKey, double mix) {
|
||||
RiveCoreContext.setString(object, propertyKey, value);
|
||||
}
|
||||
|
||||
@override
|
||||
void applyInterpolation(Core<CoreContext> object, int propertyKey,
|
||||
double currentTime, KeyFrameString nextFrame, double mix) {
|
||||
RiveCoreContext.setString(object, propertyKey, value);
|
||||
}
|
||||
|
||||
@override
|
||||
void valueChanged(String from, String to) {}
|
||||
}
|
@ -26,7 +26,6 @@ abstract class LayerState extends LayerStateBase {
|
||||
_transitions.remove(transition);
|
||||
}
|
||||
|
||||
|
||||
StateInstance makeInstance();
|
||||
|
||||
@override
|
||||
|
@ -6,7 +6,6 @@ class LinearAnimationInstance {
|
||||
final LinearAnimation animation;
|
||||
|
||||
double _time = 0;
|
||||
double _lastTime = 0;
|
||||
double _totalTime = 0;
|
||||
double _lastTotalTime = 0;
|
||||
int _direction = 1;
|
||||
@ -21,9 +20,7 @@ class LinearAnimationInstance {
|
||||
LinearAnimationInstance(this.animation)
|
||||
: _time =
|
||||
(animation.enableWorkArea ? animation.workStart : 0).toDouble() /
|
||||
animation.fps {
|
||||
_lastTime = _time;
|
||||
}
|
||||
animation.fps;
|
||||
|
||||
/// Note that when time is set, the direction will be changed to 1
|
||||
set time(double value) {
|
||||
@ -33,7 +30,7 @@ class LinearAnimationInstance {
|
||||
// Make sure to keep last and total in relative lockstep so state machines
|
||||
// can track change even when setting time.
|
||||
var diff = _totalTime - _lastTotalTime;
|
||||
_lastTime = _time = _totalTime = value;
|
||||
_time = _totalTime = value;
|
||||
_lastTotalTime = _totalTime - diff;
|
||||
_direction = 1;
|
||||
}
|
||||
@ -41,9 +38,6 @@ class LinearAnimationInstance {
|
||||
/// Returns the current time position of the animation in seconds
|
||||
double get time => _time;
|
||||
|
||||
/// Returns the time the position was at when the previous advance was called.
|
||||
double get lastTime => _lastTime;
|
||||
|
||||
/// Direction should only be +1 or -1
|
||||
set direction(int value) => _direction = value == -1 ? -1 : 1;
|
||||
|
||||
@ -70,7 +64,6 @@ class LinearAnimationInstance {
|
||||
var deltaSeconds = elapsedSeconds * animation.speed * _direction;
|
||||
_lastTotalTime = _totalTime;
|
||||
_totalTime += deltaSeconds;
|
||||
_lastTime = _time;
|
||||
_time += deltaSeconds;
|
||||
|
||||
double frames = _time * animation.fps;
|
||||
@ -84,40 +77,47 @@ class LinearAnimationInstance {
|
||||
_didLoop = false;
|
||||
_spilledTime = 0;
|
||||
|
||||
int direction = animation.speed < 0 ? -_direction : _direction;
|
||||
switch (animation.loop) {
|
||||
case Loop.oneShot:
|
||||
if (frames > end) {
|
||||
if (direction == 1 && frames > end) {
|
||||
keepGoing = false;
|
||||
_spilledTime = (frames - end) / fps;
|
||||
frames = end.toDouble();
|
||||
_time = frames / fps;
|
||||
_didLoop = true;
|
||||
} else if (direction == -1 && frames < start) {
|
||||
keepGoing = false;
|
||||
_spilledTime = (start - frames) / fps;
|
||||
frames = start.toDouble();
|
||||
_time = frames / fps;
|
||||
_didLoop = true;
|
||||
}
|
||||
break;
|
||||
case Loop.loop:
|
||||
if (frames >= end) {
|
||||
if (direction == 1 && frames >= end) {
|
||||
_spilledTime = (frames - end) / fps;
|
||||
frames = _time * fps;
|
||||
frames = start + (frames - start) % range;
|
||||
_time = frames / fps;
|
||||
_didLoop = true;
|
||||
} else if (direction == -1 && frames <= start) {
|
||||
_spilledTime = (start - frames) / fps;
|
||||
frames = _time * fps;
|
||||
frames = end - (start - frames) % range;
|
||||
_time = frames / fps;
|
||||
_didLoop = true;
|
||||
}
|
||||
break;
|
||||
case Loop.pingPong:
|
||||
// ignore: literal_only_boolean_expressions
|
||||
while (true) {
|
||||
if (_direction == 1 && frames >= end) {
|
||||
if (direction == 1 && frames >= end) {
|
||||
_spilledTime = (frames - end) / animation.fps;
|
||||
_direction = -1;
|
||||
frames = end + (end - frames);
|
||||
_time = frames / animation.fps;
|
||||
_didLoop = true;
|
||||
} else if (_direction == -1 && frames < start) {
|
||||
} else if (direction == -1 && frames < start) {
|
||||
_spilledTime = (start - frames) / animation.fps;
|
||||
_direction = 1;
|
||||
frames = start + (start - frames);
|
||||
_time = frames / animation.fps;
|
||||
_didLoop = true;
|
||||
} else {
|
||||
// we're within the range, we can stop fixing. We do this in a
|
||||
// loop to fix conditions when time has advanced so far that we've
|
||||
@ -126,7 +126,10 @@ class LinearAnimationInstance {
|
||||
// advanced on regular intervals.
|
||||
break;
|
||||
}
|
||||
_lastTime = _time;
|
||||
_time = frames / animation.fps;
|
||||
_direction *= -1;
|
||||
direction *= -1;
|
||||
_didLoop = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ class StateTransition extends StateTransitionBase {
|
||||
@override
|
||||
void onAddedDirty() {}
|
||||
|
||||
|
||||
bool get isDisabled => (flags & StateTransitionFlags.disabled) != 0;
|
||||
bool get pauseOnExit => (flags & StateTransitionFlags.pauseOnExit) != 0;
|
||||
bool get enableExitTime => (flags & StateTransitionFlags.enableExitTime) != 0;
|
||||
|
@ -93,9 +93,6 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
|
||||
Iterable<StateMachine> get stateMachines =>
|
||||
_animations.whereType<StateMachine>();
|
||||
|
||||
/// Does this artboard have animations?
|
||||
bool get hasAnimations => _animations.isNotEmpty;
|
||||
|
||||
int _dirtDepth = 0;
|
||||
|
||||
/// Iterate each component and call callback for it.
|
||||
@ -327,7 +324,7 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
|
||||
for (var drawable = _firstDrawable;
|
||||
drawable != null;
|
||||
drawable = drawable.prev) {
|
||||
if (drawable.isHidden) {
|
||||
if (drawable.isHidden || drawable.renderOpacity == 0) {
|
||||
continue;
|
||||
}
|
||||
drawable.draw(canvas);
|
||||
|
46
lib/src/rive_core/assets/font_asset.dart
Normal file
46
lib/src/rive_core/assets/font_asset.dart
Normal file
@ -0,0 +1,46 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:rive/src/generated/assets/font_asset_base.dart';
|
||||
import 'package:rive_common/rive_text.dart';
|
||||
|
||||
export 'package:rive/src/generated/assets/font_asset_base.dart';
|
||||
|
||||
class FontAsset extends FontAssetBase {
|
||||
final Set<VoidCallback> _decodedCallbacks = {};
|
||||
|
||||
/// Call [callback] when the font is ready. Set [notifyAlreadyDecoded] to
|
||||
/// specify if you want to be called if the font is already decoded.
|
||||
bool whenDecoded(VoidCallback callback, {bool notifyAlreadyDecoded = true}) {
|
||||
if (font != null) {
|
||||
if (notifyAlreadyDecoded) {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_decodedCallbacks.add(callback);
|
||||
return false;
|
||||
}
|
||||
|
||||
Font? font;
|
||||
@override
|
||||
Future<void> decode(Uint8List bytes) async {
|
||||
font = Font.decode(bytes);
|
||||
var callbacks = _decodedCallbacks.toList(growable: false);
|
||||
_decodedCallbacks.clear();
|
||||
for (final callback in callbacks) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onRemoved() {
|
||||
super.onRemoved();
|
||||
font?.dispose();
|
||||
font = null;
|
||||
}
|
||||
|
||||
@override
|
||||
String get fileExtension => 'ttf';
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/component_base.dart';
|
||||
import 'package:rive/src/rive_core/artboard.dart';
|
||||
import 'package:rive/src/rive_core/container_component.dart';
|
||||
|
@ -46,5 +46,4 @@ class ComponentFlags {
|
||||
/// End of TransformComponentConstraint
|
||||
///
|
||||
/// ----------
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import 'package:rive/src/rive_core/component.dart';
|
||||
import 'package:rive/src/rive_core/draw_rules.dart';
|
||||
import 'package:rive/src/rive_core/drawable.dart';
|
||||
|
||||
export 'package:rive/src/core/core.dart';
|
||||
|
||||
typedef bool DescentCallback(Component component);
|
||||
|
||||
abstract class ContainerComponent extends ContainerComponentBase {
|
||||
|
@ -6,6 +6,7 @@ import 'package:rive/src/rive_core/assets/file_asset.dart';
|
||||
import 'package:rive/src/rive_core/assets/image_asset.dart';
|
||||
import 'package:rive/src/rive_core/bones/skinnable.dart';
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
import 'package:rive/src/rive_core/container_component.dart';
|
||||
import 'package:rive/src/rive_core/shapes/mesh.dart';
|
||||
import 'package:rive/src/rive_core/shapes/mesh_vertex.dart';
|
||||
import 'package:rive_common/math.dart';
|
||||
@ -44,7 +45,8 @@ class Image extends ImageBase
|
||||
|
||||
final paint = ui.Paint()
|
||||
..color = ui.Color.fromRGBO(0, 0, 0, renderOpacity)
|
||||
..filterQuality = ui.FilterQuality.high;
|
||||
..filterQuality = ui.FilterQuality.high
|
||||
..blendMode = blendMode;
|
||||
|
||||
final width = asset!.width;
|
||||
final height = asset!.height;
|
||||
|
@ -34,7 +34,7 @@ class Fill extends FillBase {
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, Path path) {
|
||||
if (!isVisible) {
|
||||
if (!isVisible || renderOpacity == 0) {
|
||||
return;
|
||||
}
|
||||
path.fillType = fillType;
|
||||
|
@ -20,7 +20,7 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator {
|
||||
/// this container.
|
||||
final List<GradientStop> gradientStops = [];
|
||||
|
||||
bool _paintsInWorldSpace = true;
|
||||
bool _paintsInWorldSpace = false;
|
||||
bool get paintsInWorldSpace => _paintsInWorldSpace;
|
||||
set paintsInWorldSpace(bool value) {
|
||||
if (_paintsInWorldSpace == value) {
|
||||
@ -65,11 +65,17 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator {
|
||||
|
||||
/// Mark the gradient stops as changed. This will re-sort the stops and
|
||||
/// rebuild the necessary gradients in the next update cycle.
|
||||
void markStopsDirty() => addDirt(ComponentDirt.stops | ComponentDirt.paint);
|
||||
void markStopsDirty() {
|
||||
addDirt(ComponentDirt.stops | ComponentDirt.paint);
|
||||
markPaintDirty();
|
||||
}
|
||||
|
||||
/// Mark the gradient as needing to be rebuilt. This is a more efficient
|
||||
/// version of markStopsDirty as it won't re-sort the stops.
|
||||
void markGradientDirty() => addDirt(ComponentDirt.paint);
|
||||
void markGradientDirty() {
|
||||
addDirt(ComponentDirt.paint);
|
||||
markPaintDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
void update(int dirt) {
|
||||
@ -120,23 +126,29 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator {
|
||||
@override
|
||||
void startXChanged(double from, double to) {
|
||||
addDirt(ComponentDirt.transform);
|
||||
markPaintDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
void startYChanged(double from, double to) {
|
||||
addDirt(ComponentDirt.transform);
|
||||
markPaintDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
void endXChanged(double from, double to) {
|
||||
addDirt(ComponentDirt.transform);
|
||||
markPaintDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
void endYChanged(double from, double to) {
|
||||
addDirt(ComponentDirt.transform);
|
||||
markPaintDirty();
|
||||
}
|
||||
|
||||
void markPaintDirty() => shapePaintContainer?.addDirt(ComponentDirt.paint);
|
||||
|
||||
@override
|
||||
void onAdded() {
|
||||
super.onAdded();
|
||||
@ -148,7 +160,7 @@ class LinearGradient extends LinearGradientBase with ShapePaintMutator {
|
||||
syncColor();
|
||||
// We don't need to rebuild anything, just let our shape know we should
|
||||
// repaint.
|
||||
shapePaintContainer!.addDirt(ComponentDirt.paint);
|
||||
markPaintDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:rive/src/generated/shapes/paint/shape_paint_base.dart';
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
|
@ -84,7 +84,7 @@ class Stroke extends StrokeBase {
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, Path path) {
|
||||
if (!isVisible) {
|
||||
if (!isVisible || renderOpacity == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
import 'package:rive/src/rive_core/container_component.dart';
|
||||
import 'package:rive/src/rive_core/shapes/paint/fill.dart';
|
||||
import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart';
|
||||
import 'package:rive/src/rive_core/shapes/paint/stroke.dart';
|
||||
|
@ -25,7 +25,8 @@ import 'package:rive/src/rive_core/shapes/shape.dart';
|
||||
import 'package:rive_common/math.dart';
|
||||
|
||||
/// Callback signature for state machine state changes
|
||||
typedef OnStateChange = void Function(String, String);
|
||||
typedef OnStateChange = void Function(
|
||||
String stateMachineName, String stateName);
|
||||
|
||||
/// Callback signature for layer state changes
|
||||
typedef OnLayerStateChange = void Function(LayerState);
|
||||
|
40
lib/src/rive_core/text/styled_text.dart
Normal file
40
lib/src/rive_core/text/styled_text.dart
Normal file
@ -0,0 +1,40 @@
|
||||
import 'package:rive_common/rive_text.dart';
|
||||
import 'package:rive_common/utilities.dart';
|
||||
|
||||
class StyledText {
|
||||
final String value;
|
||||
final List<TextRun> runs;
|
||||
|
||||
factory StyledText(String text, List<TextRun> runs) {
|
||||
assert(runs.isNotEmpty);
|
||||
var extendedRuns = runs.take(runs.length - 1).toList();
|
||||
extendedRuns
|
||||
.add(runs.last.copyWith(unicharCount: runs.last.unicharCount + 1));
|
||||
return StyledText.exact(text + ' ', extendedRuns);
|
||||
}
|
||||
|
||||
factory StyledText.empty(TextRun run) => StyledText('', [run]);
|
||||
|
||||
StyledText withoutLastCharacter() {
|
||||
assert(value.isNotEmpty);
|
||||
var shortenedRuns = runs.take(runs.length - 1).toList();
|
||||
if (runs.last.unicharCount > 1) {
|
||||
// Only add the last run if it's not 0 length.
|
||||
shortenedRuns
|
||||
.add(runs.last.copyWith(unicharCount: runs.last.unicharCount - 1));
|
||||
}
|
||||
return StyledText.exact(
|
||||
value.substring(0, value.length - 1), shortenedRuns);
|
||||
}
|
||||
|
||||
StyledText.exact(this.value, this.runs);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is StyledText &&
|
||||
other.value == value &&
|
||||
iterableEquals(other.runs, runs);
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(value, Object.hashAll(runs));
|
||||
}
|
382
lib/src/rive_core/text/text.dart
Normal file
382
lib/src/rive_core/text/text.dart
Normal file
@ -0,0 +1,382 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rive/src/generated/text/text_base.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
import 'package:rive/src/rive_core/text/styled_text.dart';
|
||||
import 'package:rive/src/rive_core/text/text_style.dart' as rive;
|
||||
import 'package:rive/src/rive_core/text/text_style_container.dart';
|
||||
import 'package:rive/src/rive_core/text/text_value_run.dart';
|
||||
import 'package:rive_common/rive_text.dart';
|
||||
|
||||
export 'package:rive/src/generated/text/text_base.dart';
|
||||
|
||||
enum TextSizing {
|
||||
autoWidth,
|
||||
autoHeight,
|
||||
fixed,
|
||||
}
|
||||
|
||||
enum TextOverflow {
|
||||
visible,
|
||||
hidden,
|
||||
clipped,
|
||||
ellipsis,
|
||||
}
|
||||
|
||||
class Text extends TextBase with TextStyleContainer {
|
||||
TextShapeResult? _shape;
|
||||
// Shapes that should be cleaned before next shaping call.
|
||||
final List<TextShapeResult> _cleanupShapes = [];
|
||||
BreakLinesResult? _lines;
|
||||
// TextShapeResult? get shape => _shape;
|
||||
BreakLinesResult? get lines => _lines;
|
||||
|
||||
bool get isEmpty => runs.isEmpty || !runs.any((run) => run.text.isNotEmpty);
|
||||
|
||||
StyledText makeStyled(Font defaultFont, {bool forEditing = false}) {
|
||||
final List<TextRun> textRuns = [];
|
||||
final buffer = StringBuffer();
|
||||
int runIndex = 0;
|
||||
for (final run in runs) {
|
||||
if (run.text.isEmpty) {
|
||||
runIndex++;
|
||||
continue;
|
||||
}
|
||||
buffer.write(run.text);
|
||||
textRuns.add(TextRun(
|
||||
font: run.style?.font ?? defaultFont,
|
||||
fontSize: run.style?.fontSize ?? 16,
|
||||
unicharCount: run.text.codeUnits.length,
|
||||
styleId: runIndex++,
|
||||
));
|
||||
}
|
||||
// Couldn't fit anything?
|
||||
if (textRuns.isEmpty && runs.isNotEmpty) {
|
||||
var run = runs.first;
|
||||
textRuns.add(TextRun(
|
||||
font: run.style?.font ?? defaultFont,
|
||||
fontSize: run.style?.fontSize ?? 16,
|
||||
unicharCount: run.text.codeUnits.length,
|
||||
styleId: 0,
|
||||
));
|
||||
}
|
||||
|
||||
// We keep an empty space at the end of the buffer if it's for editing
|
||||
// purposes (we need to know where the final cursor goes and we want some
|
||||
// sense of shape even when completely empty).
|
||||
return forEditing || buffer.isEmpty
|
||||
? StyledText(buffer.toString(), textRuns)
|
||||
: StyledText.exact(buffer.toString(), textRuns);
|
||||
}
|
||||
|
||||
String get text {
|
||||
final buffer = StringBuffer();
|
||||
for (final run in runs) {
|
||||
buffer.write(run.text);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/// [defaultFont] will be removed when we add asset font options.
|
||||
TextShapeResult? shape(Font defaultFont) {
|
||||
if (_shape != null) {
|
||||
return _shape;
|
||||
}
|
||||
var styled = makeStyled(defaultFont);
|
||||
return _shape = defaultFont.shape(
|
||||
styled.value,
|
||||
styled.runs,
|
||||
);
|
||||
}
|
||||
|
||||
void _disposeShape() {
|
||||
for (final shape in _cleanupShapes) {
|
||||
shape.dispose();
|
||||
}
|
||||
_cleanupShapes.clear();
|
||||
_shape = null;
|
||||
}
|
||||
|
||||
rive.TextStyle? styleFromShaperId(int id) => runFromShaperId(id)?.style;
|
||||
TextValueRun? runFromShaperId(int id) => id < _runs.length ? _runs[id] : null;
|
||||
|
||||
List<TextValueRun> _runs = [];
|
||||
Iterable<TextValueRun> get runs => _runs;
|
||||
|
||||
void _syncRuns() {
|
||||
_runs = children.whereType<TextValueRun>().toList(growable: false);
|
||||
updateStyles();
|
||||
}
|
||||
|
||||
@override
|
||||
void onAdded() {
|
||||
super.onAdded();
|
||||
_syncRuns();
|
||||
}
|
||||
|
||||
|
||||
// We cache the text drawing into a display list so subsequent draws are
|
||||
// faster.
|
||||
Picture? _textPicture;
|
||||
|
||||
final Size _size = Size.zero;
|
||||
|
||||
static const double paragraphSpacing = 20;
|
||||
|
||||
void forEachGlyph(
|
||||
bool Function(LineRunGlyph, double, double, GlyphLine) callback) {
|
||||
var lines = _lines;
|
||||
var shape = _shape;
|
||||
if (lines == null || shape == null) {
|
||||
return;
|
||||
}
|
||||
double y = 0;
|
||||
double maxX = 0;
|
||||
var paragraphIndex = 0;
|
||||
|
||||
for (final paragraphLines in lines) {
|
||||
final paragraph = shape.paragraphs[paragraphIndex++];
|
||||
for (final line in paragraphLines) {
|
||||
double x = line.startX;
|
||||
for (final glyphInfo in line.glyphs(paragraph)) {
|
||||
var run = glyphInfo.run;
|
||||
|
||||
if (!callback(glyphInfo, x, y, line)) {
|
||||
return;
|
||||
}
|
||||
|
||||
x += run.advanceAt(glyphInfo.index);
|
||||
}
|
||||
if (x > maxX) {
|
||||
maxX = x;
|
||||
}
|
||||
}
|
||||
if (paragraphLines.isNotEmpty) {
|
||||
y += paragraphLines.last.bottom;
|
||||
}
|
||||
y += paragraphSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas) {
|
||||
var lines = _lines;
|
||||
var shape = _shape;
|
||||
if (lines == null || shape == null) {
|
||||
return;
|
||||
}
|
||||
if (_textPicture == null) {
|
||||
var recorder = PictureRecorder();
|
||||
var canvas = Canvas(recorder);
|
||||
|
||||
double y = 0;
|
||||
double maxX = 0;
|
||||
var paragraphIndex = 0;
|
||||
int ellipsisLine = -1;
|
||||
bool isEllipsisLineLast = false;
|
||||
|
||||
// Find the line to put the ellipsis on (line before the one that
|
||||
// overflows).
|
||||
if (overflow == TextOverflow.ellipsis && sizing == TextSizing.fixed) {
|
||||
int lastLineIndex = -1;
|
||||
for (final paragraphLines in lines) {
|
||||
for (final line in paragraphLines) {
|
||||
lastLineIndex++;
|
||||
if (y + line.bottom <= height) {
|
||||
ellipsisLine++;
|
||||
}
|
||||
}
|
||||
|
||||
if (paragraphLines.isNotEmpty) {
|
||||
y += paragraphLines.last.bottom;
|
||||
}
|
||||
y += paragraphSpacing;
|
||||
}
|
||||
if (ellipsisLine == -1) {
|
||||
// Nothing fits, just show the first line and ellipse it.
|
||||
ellipsisLine = 0;
|
||||
}
|
||||
isEllipsisLineLast = lastLineIndex == ellipsisLine;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
int lineIndex = 0;
|
||||
outer:
|
||||
for (final paragraphLines in lines) {
|
||||
final paragraph = shape.paragraphs[paragraphIndex++];
|
||||
for (final line in paragraphLines) {
|
||||
switch (overflow) {
|
||||
case TextOverflow.hidden:
|
||||
if (sizing == TextSizing.fixed && y + line.bottom > height) {
|
||||
break outer;
|
||||
}
|
||||
break;
|
||||
case TextOverflow.clipped:
|
||||
if (sizing == TextSizing.fixed && y + line.top > height) {
|
||||
break outer;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
double x = line.startX;
|
||||
for (final glyphInfo in lineIndex == ellipsisLine
|
||||
? line.glyphsWithEllipsis(
|
||||
width,
|
||||
paragraph: paragraph,
|
||||
isLastLine: isEllipsisLineLast,
|
||||
cleanupShapes: _cleanupShapes,
|
||||
)
|
||||
: line.glyphs(paragraph)) {
|
||||
var run = glyphInfo.run;
|
||||
var font = run.font;
|
||||
|
||||
var path = font.getUiPath(run.glyphIdAt(glyphInfo.index));
|
||||
|
||||
// canvas.save();
|
||||
// canvas.transform();
|
||||
var renderPath =
|
||||
path.transform(glyphInfo.renderTransform(x, y + line.baseline));
|
||||
var style = styleFromShaperId(run.styleId);
|
||||
if (style == null || style.shapePaints.isEmpty) {
|
||||
canvas.drawPath(
|
||||
renderPath,
|
||||
Paint()..color = const Color(0xFFFFFFFF),
|
||||
);
|
||||
} else {
|
||||
for (final shapePaint in style.shapePaints) {
|
||||
if (!shapePaint.isVisible) {
|
||||
continue;
|
||||
}
|
||||
canvas.drawPath(
|
||||
renderPath,
|
||||
shapePaint.paint,
|
||||
);
|
||||
}
|
||||
}
|
||||
// canvas.restore();
|
||||
|
||||
x += run.advanceAt(glyphInfo.index);
|
||||
}
|
||||
if (x > maxX) {
|
||||
maxX = x;
|
||||
}
|
||||
if (lineIndex == ellipsisLine) {
|
||||
break outer;
|
||||
}
|
||||
lineIndex++;
|
||||
}
|
||||
if (paragraphLines.isNotEmpty) {
|
||||
y += paragraphLines.last.bottom;
|
||||
}
|
||||
y += paragraphSpacing;
|
||||
}
|
||||
|
||||
_textPicture = recorder.endRecording();
|
||||
}
|
||||
|
||||
canvas.save();
|
||||
canvas.transform(worldTransform.mat4);
|
||||
if (overflow == TextOverflow.clipped) {
|
||||
canvas.clipRect(Offset.zero & _size);
|
||||
}
|
||||
canvas.drawPicture(_textPicture!);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
void markShapeDirty() {
|
||||
_disposeShape();
|
||||
addDirt(ComponentDirt.path);
|
||||
}
|
||||
|
||||
// TODO: figure out asset system
|
||||
static Font? _defaultFont;
|
||||
|
||||
void markPaintDirty() {
|
||||
_textPicture?.dispose();
|
||||
_textPicture = null;
|
||||
}
|
||||
|
||||
void computeShape() {
|
||||
markPaintDirty();
|
||||
_shape = null;
|
||||
_lines?.dispose();
|
||||
_lines = null;
|
||||
if (runs.isEmpty) {
|
||||
return;
|
||||
}
|
||||
_shape = shape(_defaultFont!);
|
||||
_cleanupShapes.add(_shape!);
|
||||
|
||||
_lines =
|
||||
_shape?.breakLines(sizing == TextSizing.autoWidth ? -1 : width, align);
|
||||
}
|
||||
|
||||
@override
|
||||
void update(int dirt) {
|
||||
super.update(dirt);
|
||||
if (dirt & ComponentDirt.path != 0) {
|
||||
// Hardcode font for now.
|
||||
if (_defaultFont == null) {
|
||||
rootBundle.load('assets/fonts/Inter-Regular.ttf').then((fontAsset) {
|
||||
_defaultFont = Font.decode(fontAsset.buffer.asUint8List());
|
||||
// Reshape now that we have font.
|
||||
markShapeDirty();
|
||||
});
|
||||
} else {
|
||||
computeShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onRemoved() {
|
||||
super.onRemoved();
|
||||
_disposeShape();
|
||||
_lines?.dispose();
|
||||
disposeStyleContainer();
|
||||
_lines = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void alignValueChanged(int from, int to) => markShapeDirty();
|
||||
|
||||
TextAlign get align => TextAlign.values[alignValue];
|
||||
set align(TextAlign value) => alignValue = value.index;
|
||||
|
||||
@override
|
||||
void heightChanged(double from, double to) {
|
||||
if (sizing == TextSizing.fixed) {
|
||||
markShapeDirty();
|
||||
}
|
||||
}
|
||||
|
||||
TextSizing get sizing => TextSizing.values[sizingValue];
|
||||
set sizing(TextSizing value) => sizingValue = value.index;
|
||||
TextOverflow get overflow {
|
||||
return TextOverflow.values[overflowValue];
|
||||
}
|
||||
|
||||
set overflow(TextOverflow value) => overflowValue = value.index;
|
||||
|
||||
@override
|
||||
void sizingValueChanged(int from, int to) {
|
||||
markShapeDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
void widthChanged(double from, double to) {
|
||||
if (sizing != TextSizing.autoWidth) {
|
||||
markShapeDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void overflowValueChanged(int from, int to) {
|
||||
if (sizing != TextSizing.autoWidth) {
|
||||
markShapeDirty();
|
||||
}
|
||||
}
|
||||
}
|
207
lib/src/rive_core/text/text_style.dart
Normal file
207
lib/src/rive_core/text/text_style.dart
Normal file
@ -0,0 +1,207 @@
|
||||
import 'package:rive/src/generated/text/text_style_base.dart';
|
||||
import 'package:rive/src/rive_core/artboard.dart';
|
||||
import 'package:rive/src/rive_core/assets/file_asset.dart';
|
||||
import 'package:rive/src/rive_core/assets/font_asset.dart';
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
import 'package:rive/src/rive_core/shapes/paint/shape_paint.dart';
|
||||
import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart';
|
||||
import 'package:rive/src/rive_core/shapes/shape_paint_container.dart';
|
||||
import 'package:rive/src/rive_core/text/text.dart';
|
||||
import 'package:rive/src/rive_core/text/text_style_axis.dart';
|
||||
import 'package:rive/src/rive_core/text/text_value_run.dart';
|
||||
import 'package:rive_common/math.dart';
|
||||
import 'package:rive_common/rive_text.dart';
|
||||
|
||||
export 'package:rive/src/generated/text/text_style_base.dart';
|
||||
|
||||
class TextVariationHelper extends Component {
|
||||
final TextStyle style;
|
||||
Font? _font;
|
||||
|
||||
@override
|
||||
Artboard? get artboard => style.artboard;
|
||||
|
||||
Font? get font => _font;
|
||||
|
||||
TextVariationHelper(this.style) {
|
||||
style.markRebuildDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
void update(int dirt) {
|
||||
_font?.dispose();
|
||||
_font = style._makeVariableFont();
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_font?.dispose();
|
||||
_font = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void buildDependencies() {
|
||||
var text = style.text;
|
||||
if (text != null) {
|
||||
text.artboard?.addDependent(this);
|
||||
addDependent(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TextStyle extends TextStyleBase
|
||||
with ShapePaintContainer, FileAssetReferencer<FontAsset> {
|
||||
final Set<TextValueRun> _referencers = {};
|
||||
Text? get text => parent as Text?;
|
||||
final Set<TextStyleAxis> _variations = {};
|
||||
Iterable<TextStyleAxis> get variations => _variations;
|
||||
|
||||
Iterable<FontAxis> get variableAxes => asset?.font?.axes ?? [];
|
||||
bool get hasVariableAxes => asset?.font?.axes.isNotEmpty ?? false;
|
||||
|
||||
TextVariationHelper? _variationHelper;
|
||||
TextVariationHelper? get variationHelper => _variationHelper;
|
||||
|
||||
Font? _makeVariableFont() => asset?.font?.makeVariation(
|
||||
_variations.map((axis) => FontAxisCoord(axis.tag, axis.axisValue)));
|
||||
|
||||
Font? get font => _variationHelper?.font ?? asset?.font;
|
||||
|
||||
List<ShapePaint> get shapePaints =>
|
||||
fills.cast<ShapePaint>().toList() + strokes.cast<ShapePaint>().toList();
|
||||
|
||||
/// An identifier used by the shaper to remap style ids as text runs are
|
||||
/// converted to glyph runs.
|
||||
int shaperId = -1;
|
||||
|
||||
@override
|
||||
void fontSizeChanged(double from, double to) => _markShapeDirty();
|
||||
|
||||
void _markShapeDirty() {
|
||||
for (final run in _referencers) {
|
||||
run.markShapeDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void update(int dirt) {}
|
||||
|
||||
/// Let the style know that a run references it.
|
||||
void ref(TextValueRun run) {
|
||||
_referencers.add(run);
|
||||
}
|
||||
|
||||
void deref(TextValueRun run) {
|
||||
_referencers.remove(run);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => '${super.toString()} -> FontSize($fontSize)';
|
||||
|
||||
@override
|
||||
void buildDependencies() {
|
||||
parent?.addDependent(this);
|
||||
_variationHelper?.buildDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
set asset(FontAsset? value) {
|
||||
if (asset == value) {
|
||||
return;
|
||||
}
|
||||
_variations.toSet().forEach(context.removeObject);
|
||||
super.asset = value;
|
||||
if (asset?.whenDecoded(_fontDecoded, notifyAlreadyDecoded: false) ??
|
||||
false) {
|
||||
// Already decoded.
|
||||
_markShapeDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void fontAssetIdChanged(int from, int to) {
|
||||
asset = context.resolve(to);
|
||||
}
|
||||
|
||||
void _fontDecoded() => _markShapeDirty();
|
||||
|
||||
@override
|
||||
void onAddedDirty() {
|
||||
super.onAddedDirty();
|
||||
asset = context.resolve(fontAssetId);
|
||||
}
|
||||
|
||||
@override
|
||||
void onDirty(int mask) {
|
||||
super.onDirty(mask);
|
||||
if ((mask & ComponentDirt.paint) != 0) {
|
||||
text?.markPaintDirty();
|
||||
}
|
||||
if ((mask & ComponentDirt.textShape) != 0) {
|
||||
text?.markShapeDirty();
|
||||
_variationHelper?.addDirt(ComponentDirt.textShape);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onFillsChanged() {
|
||||
text?.markPaintDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
void onPaintMutatorChanged(ShapePaintMutator mutator) {
|
||||
text?.markPaintDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
void onStrokesChanged() {
|
||||
text?.markPaintDirty();
|
||||
}
|
||||
|
||||
@override
|
||||
Mat2D get worldTransform => text?.worldTransform ?? Mat2D.identity;
|
||||
|
||||
@override
|
||||
Vec2D get worldTranslation => text?.worldTranslation ?? Vec2D();
|
||||
|
||||
@override
|
||||
void childAdded(Component component) {
|
||||
super.childAdded(component);
|
||||
if (component is TextStyleAxis) {
|
||||
if (_variations.add(component)) {
|
||||
_variationHelper ??= TextVariationHelper(this);
|
||||
addDirt(ComponentDirt.textShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void childRemoved(Component component) {
|
||||
super.childRemoved(component);
|
||||
if (component is TextStyleAxis) {
|
||||
if (_variations.remove(component)) {
|
||||
addDirt(ComponentDirt.textShape);
|
||||
if (_variations.isEmpty) {
|
||||
_variationHelper?.dispose();
|
||||
_variationHelper = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onRemoved() {
|
||||
super.onRemoved();
|
||||
_variationHelper?.dispose();
|
||||
_variationHelper = null;
|
||||
}
|
||||
|
||||
@override
|
||||
int get assetId => fontAssetId;
|
||||
|
||||
@override
|
||||
set assetId(int value) => fontAssetId = value;
|
||||
|
||||
@override
|
||||
int get assetIdPropertyKey => TextStyleBase.fontAssetIdPropertyKey;
|
||||
}
|
23
lib/src/rive_core/text/text_style_axis.dart
Normal file
23
lib/src/rive_core/text/text_style_axis.dart
Normal file
@ -0,0 +1,23 @@
|
||||
import 'package:rive/src/generated/text/text_style_axis_base.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
import 'package:rive/src/rive_core/text/text_style.dart';
|
||||
import 'package:rive_common/rive_text.dart';
|
||||
|
||||
export 'package:rive/src/generated/text/text_style_axis_base.dart';
|
||||
|
||||
class TextStyleAxis extends TextStyleAxisBase {
|
||||
@override
|
||||
bool validate() => super.validate() && parent is TextStyle;
|
||||
|
||||
String get tagName => FontAxis.tagToName(tag);
|
||||
|
||||
@override
|
||||
void update(int dirt) {}
|
||||
|
||||
@override
|
||||
void axisValueChanged(double from, double to) =>
|
||||
parent?.addDirt(ComponentDirt.textShape);
|
||||
|
||||
@override
|
||||
void tagChanged(int from, int to) => parent?.addDirt(ComponentDirt.textShape);
|
||||
}
|
65
lib/src/rive_core/text/text_style_container.dart
Normal file
65
lib/src/rive_core/text/text_style_container.dart
Normal file
@ -0,0 +1,65 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
import 'package:rive/src/rive_core/container_component.dart';
|
||||
import 'package:rive/src/rive_core/text/text_style.dart';
|
||||
import 'package:rive_common/utilities.dart';
|
||||
|
||||
/// An abstraction to give a common interface to any component that can contain
|
||||
/// TextStyles. Currently used by the [Text] object but we can later support
|
||||
/// file-wide styles by making them owned by an [Artboard] or [Backboard].
|
||||
abstract class TextStyleContainer {
|
||||
int _nextShaperId = 0;
|
||||
final Set<TextStyle> styles = {};
|
||||
final HashMap<int, TextStyle> _styleLookup = HashMap<int, TextStyle>();
|
||||
|
||||
// TextStyle? styleFromShaperId(int id) => _styleLookup[id];
|
||||
|
||||
void disposeStyleContainer() {
|
||||
_styleLookup.clear();
|
||||
styles.clear();
|
||||
}
|
||||
|
||||
bool addStyle(TextStyle style) {
|
||||
if (styles.add(style)) {
|
||||
_registerStyle(style);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _registerStyle(TextStyle style) {
|
||||
if (style.shaperId == -1) {
|
||||
style.shaperId = _nextShaperId++;
|
||||
_styleLookup[style.shaperId] = style;
|
||||
}
|
||||
}
|
||||
|
||||
ContainerChildren get children;
|
||||
void updateStyles() {
|
||||
var nextStyles = children.whereType<TextStyle>();
|
||||
if (!iterableEquals(nextStyles, styles)) {
|
||||
styles.clear();
|
||||
styles.addAll(nextStyles);
|
||||
styles.forEach(_registerStyle);
|
||||
}
|
||||
}
|
||||
|
||||
bool removeStyle(TextStyle style) {
|
||||
if (styles.remove(style)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// These usually gets auto implemented as this mixin is meant to be added to
|
||||
/// a ComponentBase. This way the implementor doesn't need to cast
|
||||
/// ShapePaintContainer to ContainerComponent/Shape/Artboard/etc.
|
||||
bool addDirt(int value, {bool recurse = false});
|
||||
|
||||
bool addDependent(Component dependent, {Component? via});
|
||||
void appendChild(Component child);
|
||||
// Mat2D get worldTransform;
|
||||
// Vec2D get worldTranslation;
|
||||
}
|
50
lib/src/rive_core/text/text_value_run.dart
Normal file
50
lib/src/rive_core/text/text_value_run.dart
Normal file
@ -0,0 +1,50 @@
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/text/text_value_run_base.dart';
|
||||
import 'package:rive/src/rive_core/text/text.dart';
|
||||
|
||||
import 'package:rive/src/rive_core/text/text_style.dart';
|
||||
export 'package:rive/src/generated/text/text_value_run_base.dart';
|
||||
|
||||
class TextValueRun extends TextValueRunBase {
|
||||
Text? get textComponent => parent as Text?;
|
||||
|
||||
TextStyle? _style;
|
||||
TextStyle? get style => _style;
|
||||
set style(TextStyle? value) {
|
||||
if (_style == value) {
|
||||
return;
|
||||
}
|
||||
_style?.deref(this);
|
||||
_style = value;
|
||||
styleId = value?.id ?? Core.missingId;
|
||||
_style?.ref(this);
|
||||
}
|
||||
|
||||
void markShapeDirty() => textComponent?.markShapeDirty();
|
||||
|
||||
@override
|
||||
void onAdded() {}
|
||||
|
||||
@override
|
||||
void styleIdChanged(int from, int to) {
|
||||
style = context.resolve(to);
|
||||
}
|
||||
|
||||
@override
|
||||
void onRemoved() {
|
||||
super.onRemoved();
|
||||
_style?.deref(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void onAddedDirty() {
|
||||
super.onAddedDirty();
|
||||
style = context.resolve(styleId);
|
||||
}
|
||||
|
||||
@override
|
||||
void update(int dirt) {}
|
||||
|
||||
@override
|
||||
void textChanged(String from, String to) => textComponent?.markShapeDirty();
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:rive/src/generated/transform_component_base.dart';
|
||||
import 'package:rive/src/rive_core/component.dart';
|
||||
import 'package:rive/src/rive_core/component_dirt.dart';
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: rive
|
||||
version: 0.10.1
|
||||
version: 0.10.2
|
||||
homepage: https://rive.app
|
||||
description: Rive 2 Flutter Runtime. This package provides runtime functionality for playing back and interacting with animations built with the Rive editor available at https://rive.app.
|
||||
repository: https://github.com/rive-app/rive-flutter
|
||||
|
@ -14,7 +14,7 @@ void main() {
|
||||
test('LinearAnimationInstance exposes direction is either +/-1', () {
|
||||
final artboard = riveFile.mainArtboard;
|
||||
|
||||
expect(artboard.hasAnimations, isTrue);
|
||||
expect(artboard.animations, isNotEmpty);
|
||||
LinearAnimationInstance instance =
|
||||
LinearAnimationInstance(artboard.animations.first as LinearAnimation);
|
||||
|
||||
@ -29,7 +29,7 @@ void main() {
|
||||
test('LinearAnimationInstance has a valid start and end time', () {
|
||||
final artboard = riveFile.mainArtboard;
|
||||
|
||||
expect(artboard.hasAnimations, isTrue);
|
||||
expect(artboard.animations, isNotEmpty);
|
||||
LinearAnimationInstance instance =
|
||||
LinearAnimationInstance(artboard.animations.first as LinearAnimation);
|
||||
|
||||
@ -49,7 +49,7 @@ void main() {
|
||||
test('LinearAnimationInstance can be reset', () {
|
||||
final artboard = riveFile.mainArtboard;
|
||||
|
||||
expect(artboard.hasAnimations, isTrue);
|
||||
expect(artboard.animations, isNotEmpty);
|
||||
LinearAnimationInstance instance =
|
||||
LinearAnimationInstance(artboard.animations.first as LinearAnimation);
|
||||
|
||||
|
Reference in New Issue
Block a user