From fae49a923970233ae4a26f264d36b757424666a5 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Wed, 27 Mar 2024 19:31:03 +0100 Subject: [PATCH 01/11] feat: Add onFinished callback to ScrollTextBoxComponent --- doc/flame/rendering/text_rendering.md | 5 +-- .../components/scroll_text_box_component.dart | 37 +++++++++++++------ .../src/components/text_box_component.dart | 9 ++++- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/doc/flame/rendering/text_rendering.md b/doc/flame/rendering/text_rendering.md index 86d544793fa..91a27434066 100644 --- a/doc/flame/rendering/text_rendering.md +++ b/doc/flame/rendering/text_rendering.md @@ -12,9 +12,8 @@ components: - `TextBoxComponent` for bounding multi-line text within a sized box, including the possibility of a typing effect - `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding scrolling -capability when the text exceeds the boundaries of the enclosing box. - -Use the `onFinished` callback to get notified when the text is completely printed. +capability when the text exceeds the boundaries of the enclosing box. Use the `onFinished` callback +to get notified when the text is completely printed. All components are showcased in diff --git a/packages/flame/lib/src/components/scroll_text_box_component.dart b/packages/flame/lib/src/components/scroll_text_box_component.dart index 45e74777b54..d87ce4ace6b 100644 --- a/packages/flame/lib/src/components/scroll_text_box_component.dart +++ b/packages/flame/lib/src/components/scroll_text_box_component.dart @@ -22,6 +22,7 @@ class ScrollTextBoxComponent extends PositionComponent { /// - [text]: The text content to be displayed. /// - [textRenderer]: Handles the rendering of the text. /// - [boxConfig]: Configuration for the text box appearance. + /// - [onFinished]: Callback will be executed after all text is displayed. /// - Other parameters include alignment, pixel ratio, and positioning /// settings. /// An assertion ensures that the [size] has positive dimensions. @@ -39,6 +40,7 @@ class ScrollTextBoxComponent extends PositionComponent { super.priority, super.key, List? children, + void Function()? onFinished, }) : assert( size.x > 0 && size.y > 0, 'size must have positive dimensions: $size', @@ -56,6 +58,7 @@ class ScrollTextBoxComponent extends PositionComponent { boxConfig: boxConfig, align: align, pixelRatio: pixelRatio, + onFinished: onFinished, ); _scrollTextBoxComponent.setOwnerComponent = this; // Integrates the [ClipComponent] for managing @@ -89,12 +92,16 @@ class ScrollTextBoxComponent extends PositionComponent { class _ScrollTextBoxComponent extends TextBoxComponent with DragCallbacks { double scrollBoundsY = 0.0; - int _linesScrolled = 0; late final ClipComponent clipComponent; late ScrollTextBoxComponent _owner; + /// Callback function to be executed after all text is displayed. + void Function()? onFinished; + + bool _isOnFinishedExecuted = false; + _ScrollTextBoxComponent({ String? text, T? textRenderer, @@ -104,34 +111,42 @@ class _ScrollTextBoxComponent extends TextBoxComponent super.position, super.scale, double super.angle = 0.0, + this.onFinished, }) : super( text: text ?? '', textRenderer: textRenderer ?? TextPaint(), - boxConfig: boxConfig ?? const TextBoxConfig(), + boxConfig: boxConfig ?? TextBoxConfig(), ); @override Future onLoad() { clipComponent = parent! as ClipComponent; + newLineCallback = (double y) { + if (y > clipComponent.size.y) { + position.y = -y + clipComponent.size.y; + } + }; return super.onLoad(); } @override - Future redraw() async { - if ((currentLine + 1 - _linesScrolled) * lineHeight > - clipComponent.size.y) { - _linesScrolled++; - position.y -= lineHeight; - scrollBoundsY = -position.y; + void update(double dt) { + if (!_isOnFinishedExecuted && finished) { + _isOnFinishedExecuted = true; + scrollBoundsY = clipComponent.size.y - size.y; + if (onFinished != null) { + onFinished!(); + } } - await super.redraw(); + + super.update(dt); } @override void onDragUpdate(DragUpdateEvent event) { - if (finished && _linesScrolled > 0) { + if (finished && scrollBoundsY < 0) { position.y += event.localDelta.y; - position.y = position.y.clamp(-scrollBoundsY, 0); + position.y = position.y.clamp(scrollBoundsY, 0); } } diff --git a/packages/flame/lib/src/components/text_box_component.dart b/packages/flame/lib/src/components/text_box_component.dart index d753b9c0266..f3870a31aeb 100644 --- a/packages/flame/lib/src/components/text_box_component.dart +++ b/packages/flame/lib/src/components/text_box_component.dart @@ -79,6 +79,8 @@ class TextBoxComponent extends TextComponent { @visibleForTesting Image? cache; + Function(double)? newLineCallback; + double _currentLinePosition = 0.0; TextBoxConfig get boxConfig => _boxConfig; double get lineHeight => _lineHeight; @@ -300,7 +302,12 @@ class TextBoxComponent extends TextComponent { i * _lineHeight, ); textElement.render(canvas, position); - + if (position.y > _currentLinePosition) { + _currentLinePosition = position.y; + if (newLineCallback != null) { + newLineCallback!(_currentLinePosition + _lineHeight); + } + } charCount += lines[i].length; } } From 8b5d97abb83b4ed12a79fe7d19e05c01179bba15 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Wed, 27 Mar 2024 19:56:04 +0100 Subject: [PATCH 02/11] Fixing the analysis output --- doc/flame/rendering/text_rendering.md | 2 +- .../flame/lib/src/components/scroll_text_box_component.dart | 6 ++---- packages/flame/lib/src/components/text_box_component.dart | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/doc/flame/rendering/text_rendering.md b/doc/flame/rendering/text_rendering.md index 91a27434066..24b2cb1ba75 100644 --- a/doc/flame/rendering/text_rendering.md +++ b/doc/flame/rendering/text_rendering.md @@ -12,7 +12,7 @@ components: - `TextBoxComponent` for bounding multi-line text within a sized box, including the possibility of a typing effect - `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding scrolling -capability when the text exceeds the boundaries of the enclosing box. Use the `onFinished` callback +capability when the text exceeds the boundaries of the enclosing box. Use the `onFinished` callback to get notified when the text is completely printed. diff --git a/packages/flame/lib/src/components/scroll_text_box_component.dart b/packages/flame/lib/src/components/scroll_text_box_component.dart index d87ce4ace6b..34b93f905d0 100644 --- a/packages/flame/lib/src/components/scroll_text_box_component.dart +++ b/packages/flame/lib/src/components/scroll_text_box_component.dart @@ -115,7 +115,7 @@ class _ScrollTextBoxComponent extends TextBoxComponent }) : super( text: text ?? '', textRenderer: textRenderer ?? TextPaint(), - boxConfig: boxConfig ?? TextBoxConfig(), + boxConfig: boxConfig ?? const TextBoxConfig(), ); @override @@ -134,9 +134,7 @@ class _ScrollTextBoxComponent extends TextBoxComponent if (!_isOnFinishedExecuted && finished) { _isOnFinishedExecuted = true; scrollBoundsY = clipComponent.size.y - size.y; - if (onFinished != null) { - onFinished!(); - } + onFinished?.call(); } super.update(dt); diff --git a/packages/flame/lib/src/components/text_box_component.dart b/packages/flame/lib/src/components/text_box_component.dart index f3870a31aeb..25308209757 100644 --- a/packages/flame/lib/src/components/text_box_component.dart +++ b/packages/flame/lib/src/components/text_box_component.dart @@ -304,9 +304,7 @@ class TextBoxComponent extends TextComponent { textElement.render(canvas, position); if (position.y > _currentLinePosition) { _currentLinePosition = position.y; - if (newLineCallback != null) { - newLineCallback!(_currentLinePosition + _lineHeight); - } + newLineCallback?.call(_currentLinePosition + _lineHeight); } charCount += lines[i].length; } From 5cb6afe65f8a58734d50bd969b56f8b930e96a02 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Wed, 27 Mar 2024 23:48:27 +0100 Subject: [PATCH 03/11] Update onFinished to onComplete callback --- doc/flame/rendering/text_rendering.md | 2 +- .../components/scroll_text_box_component.dart | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/flame/rendering/text_rendering.md b/doc/flame/rendering/text_rendering.md index 24b2cb1ba75..f7befc7e67c 100644 --- a/doc/flame/rendering/text_rendering.md +++ b/doc/flame/rendering/text_rendering.md @@ -12,7 +12,7 @@ components: - `TextBoxComponent` for bounding multi-line text within a sized box, including the possibility of a typing effect - `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding scrolling -capability when the text exceeds the boundaries of the enclosing box. Use the `onFinished` callback +capability when the text exceeds the boundaries of the enclosing box. Use the `onComplete` callback to get notified when the text is completely printed. diff --git a/packages/flame/lib/src/components/scroll_text_box_component.dart b/packages/flame/lib/src/components/scroll_text_box_component.dart index 34b93f905d0..d85f15b3776 100644 --- a/packages/flame/lib/src/components/scroll_text_box_component.dart +++ b/packages/flame/lib/src/components/scroll_text_box_component.dart @@ -22,7 +22,7 @@ class ScrollTextBoxComponent extends PositionComponent { /// - [text]: The text content to be displayed. /// - [textRenderer]: Handles the rendering of the text. /// - [boxConfig]: Configuration for the text box appearance. - /// - [onFinished]: Callback will be executed after all text is displayed. + /// - [onComplete]: Callback will be executed after all text is displayed. /// - Other parameters include alignment, pixel ratio, and positioning /// settings. /// An assertion ensures that the [size] has positive dimensions. @@ -40,7 +40,7 @@ class ScrollTextBoxComponent extends PositionComponent { super.priority, super.key, List? children, - void Function()? onFinished, + void Function()? onComplete, }) : assert( size.x > 0 && size.y > 0, 'size must have positive dimensions: $size', @@ -58,7 +58,7 @@ class ScrollTextBoxComponent extends PositionComponent { boxConfig: boxConfig, align: align, pixelRatio: pixelRatio, - onFinished: onFinished, + onComplete: onComplete, ); _scrollTextBoxComponent.setOwnerComponent = this; // Integrates the [ClipComponent] for managing @@ -98,9 +98,9 @@ class _ScrollTextBoxComponent extends TextBoxComponent late ScrollTextBoxComponent _owner; /// Callback function to be executed after all text is displayed. - void Function()? onFinished; + void Function()? onComplete; - bool _isOnFinishedExecuted = false; + bool _isOnCompleteExecuted = false; _ScrollTextBoxComponent({ String? text, @@ -111,7 +111,7 @@ class _ScrollTextBoxComponent extends TextBoxComponent super.position, super.scale, double super.angle = 0.0, - this.onFinished, + this.onComplete, }) : super( text: text ?? '', textRenderer: textRenderer ?? TextPaint(), @@ -131,10 +131,10 @@ class _ScrollTextBoxComponent extends TextBoxComponent @override void update(double dt) { - if (!_isOnFinishedExecuted && finished) { - _isOnFinishedExecuted = true; + if (!_isOnCompleteExecuted && finished) { + _isOnCompleteExecuted = true; scrollBoundsY = clipComponent.size.y - size.y; - onFinished?.call(); + onComplete?.call(); } super.update(dt); From 82b9c09a1ceaf0e773e9e6464fc5ffc9d585c233 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Thu, 28 Mar 2024 01:27:05 +0100 Subject: [PATCH 04/11] Add tests for ScrollTextBoxComponent --- .../scroll_text_box_component_test.dart | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 packages/flame/test/components/scroll_text_box_component_test.dart diff --git a/packages/flame/test/components/scroll_text_box_component_test.dart b/packages/flame/test/components/scroll_text_box_component_test.dart new file mode 100644 index 00000000000..2827eabbfab --- /dev/null +++ b/packages/flame/test/components/scroll_text_box_component_test.dart @@ -0,0 +1,79 @@ +import 'package:flame/components.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; + +void main() { + group('ScrollTextBoxComponent', () { + testWithFlameGame( + 'onComplete is called when no scrolling is required', + (game) async { + final onComplete = MockOnCompleteCallback(); + + when(onComplete).thenReturn(null); + + final component = ScrollTextBoxComponent( + size: Vector2(200, 100), + text: 'Short text', + onComplete: onComplete, + ); + await game.ensureAdd(component); + + game.update(0.1); + + verify(onComplete).called(1); + }, + ); + + testWithFlameGame( + 'onComplete is called when scrolling is required', + (game) async { + final onComplete = MockOnCompleteCallback(); + + when(onComplete).thenReturn(null); + + final component = ScrollTextBoxComponent( + size: Vector2(200, 100), + text: '''Long text that will definitely require scrolling to be +fully visible in the given size of the ScrollTextBoxComponent.''', + onComplete: onComplete, + ); + await game.ensureAdd(component); + + game.update(0.1); + + verify(onComplete).called(1); + }, + ); + + testWithFlameGame( + 'Text position moves to <0 when scrolled', + (game) async { + final scrollComponent = ScrollTextBoxComponent( + size: Vector2(50, 50), + text: '''This is a test text that is long enough to require scrolling +to see the entire content. It should test whether the scrolling +functionality properly adjusts the text position.''', + onComplete: () {}, + ); + + expect(scrollComponent.children.length, greaterThan(0)); + expect(scrollComponent.children.first, isA()); + final clipCmp = scrollComponent.children.first as ClipComponent; + + expect(clipCmp.children.length, greaterThan(0)); + expect(clipCmp.children.first, isA()); + final innerScrolComponent = clipCmp.children.first as PositionComponent; + + expect(innerScrolComponent.position.y, equals(0)); + await game.ensureAdd(scrollComponent); + + expect(innerScrolComponent.position.y, lessThan(0)); + }, + ); + }); +} + +class MockOnCompleteCallback extends Mock { + void call(); +} From fde94e944f35ebb3a221eb31308d38a19094c133 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Thu, 28 Mar 2024 01:33:28 +0100 Subject: [PATCH 05/11] Corrected spelling --- .../test/components/scroll_text_box_component_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/flame/test/components/scroll_text_box_component_test.dart b/packages/flame/test/components/scroll_text_box_component_test.dart index 2827eabbfab..0f449ed7df7 100644 --- a/packages/flame/test/components/scroll_text_box_component_test.dart +++ b/packages/flame/test/components/scroll_text_box_component_test.dart @@ -63,12 +63,12 @@ functionality properly adjusts the text position.''', expect(clipCmp.children.length, greaterThan(0)); expect(clipCmp.children.first, isA()); - final innerScrolComponent = clipCmp.children.first as PositionComponent; + final innerScrollComponent = clipCmp.children.first as PositionComponent; - expect(innerScrolComponent.position.y, equals(0)); + expect(innerScrollComponent.position.y, equals(0)); await game.ensureAdd(scrollComponent); - expect(innerScrolComponent.position.y, lessThan(0)); + expect(innerScrollComponent.position.y, lessThan(0)); }, ); }); From 85cd1939b2dd739a2f83f2831a2fc1bc81649757 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Thu, 28 Mar 2024 01:37:49 +0100 Subject: [PATCH 06/11] Corrected formatting --- .../flame/test/components/scroll_text_box_component_test.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/flame/test/components/scroll_text_box_component_test.dart b/packages/flame/test/components/scroll_text_box_component_test.dart index 0f449ed7df7..0992c3cd68d 100644 --- a/packages/flame/test/components/scroll_text_box_component_test.dart +++ b/packages/flame/test/components/scroll_text_box_component_test.dart @@ -63,7 +63,8 @@ functionality properly adjusts the text position.''', expect(clipCmp.children.length, greaterThan(0)); expect(clipCmp.children.first, isA()); - final innerScrollComponent = clipCmp.children.first as PositionComponent; + final innerScrollComponent = + clipCmp.children.first as PositionComponent; expect(innerScrollComponent.position.y, equals(0)); await game.ensureAdd(scrollComponent); From 7b4a297c0b81fdc0a8fe4a09f23751331b1b7bf0 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Thu, 28 Mar 2024 14:30:17 +0100 Subject: [PATCH 07/11] Add newLineNotifier and newLinePositionNotifier to TextBoxComponent ScrollTextBoxComponent makes use of newLinePositionNotifier change/add tests change docs --- doc/flame/rendering/text_rendering.md | 4 +-- .../components/scroll_text_box_component.dart | 29 +++++++++++++++---- .../src/components/text_box_component.dart | 12 ++++++-- .../scroll_text_box_component_test.dart | 19 ++++++++++++ .../components/text_box_component_test.dart | 21 ++++++++++++++ 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/doc/flame/rendering/text_rendering.md b/doc/flame/rendering/text_rendering.md index f7befc7e67c..9b140b6f7f1 100644 --- a/doc/flame/rendering/text_rendering.md +++ b/doc/flame/rendering/text_rendering.md @@ -10,10 +10,10 @@ components: - `TextComponent` for rendering a single line of text - `TextBoxComponent` for bounding multi-line text within a sized box, including the possibility of a -typing effect +typing effect. You can use the `newLineNotifier` to be notified when a new line is added. - `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding scrolling capability when the text exceeds the boundaries of the enclosing box. Use the `onComplete` callback -to get notified when the text is completely printed. +to get notified when the text is completely printed. All components are showcased in diff --git a/packages/flame/lib/src/components/scroll_text_box_component.dart b/packages/flame/lib/src/components/scroll_text_box_component.dart index d85f15b3776..22152e5a57b 100644 --- a/packages/flame/lib/src/components/scroll_text_box_component.dart +++ b/packages/flame/lib/src/components/scroll_text_box_component.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flame/components.dart'; import 'package:flame/events.dart'; import 'package:flame/text.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/painting.dart'; /// [ScrollTextBoxComponent] configures the layout and interactivity of a @@ -15,6 +16,9 @@ import 'package:flutter/painting.dart'; /// capabilities. class ScrollTextBoxComponent extends PositionComponent { late final _ScrollTextBoxComponent _scrollTextBoxComponent; + late final ValueNotifier _newLineNotifier; + + ValueNotifier get newLineNotifier => _newLineNotifier; /// Constructor for [ScrollTextBoxComponent]. /// - [size]: Specifies the size of the text box. @@ -50,8 +54,19 @@ class ScrollTextBoxComponent extends PositionComponent { final marginBottom = boxConfig?.margins.bottom ?? 0; final innerMargins = EdgeInsets.fromLTRB(0, marginTop, 0, marginBottom); - boxConfig = (boxConfig ?? const TextBoxConfig()).copyWith(maxWidth: size.x); - + boxConfig ??= const TextBoxConfig(); + boxConfig = TextBoxConfig( + timePerChar: boxConfig.timePerChar, + dismissDelay: boxConfig.dismissDelay, + growingBox: boxConfig.growingBox, + maxWidth: size.x, + margins: EdgeInsets.fromLTRB( + boxConfig.margins.left, + 0, + boxConfig.margins.right, + 0, + ), + ); _scrollTextBoxComponent = _ScrollTextBoxComponent( text: text, textRenderer: textRenderer, @@ -60,6 +75,8 @@ class ScrollTextBoxComponent extends PositionComponent { pixelRatio: pixelRatio, onComplete: onComplete, ); + _newLineNotifier = _scrollTextBoxComponent.newLineNotifier; + _scrollTextBoxComponent.setOwnerComponent = this; // Integrates the [ClipComponent] for managing // the text box's scrollable area. @@ -121,11 +138,11 @@ class _ScrollTextBoxComponent extends TextBoxComponent @override Future onLoad() { clipComponent = parent! as ClipComponent; - newLineCallback = (double y) { - if (y > clipComponent.size.y) { - position.y = -y + clipComponent.size.y; + newLinePositionNotifier.addListener(() { + if (newLinePositionNotifier.value > clipComponent.size.y) { + position.y = -newLinePositionNotifier.value + clipComponent.size.y; } - }; + }); return super.onLoad(); } diff --git a/packages/flame/lib/src/components/text_box_component.dart b/packages/flame/lib/src/components/text_box_component.dart index 25308209757..722ade928fe 100644 --- a/packages/flame/lib/src/components/text_box_component.dart +++ b/packages/flame/lib/src/components/text_box_component.dart @@ -79,7 +79,14 @@ class TextBoxComponent extends TextComponent { @visibleForTesting Image? cache; - Function(double)? newLineCallback; + + /// Notifies when a new line is rendered. + final ValueNotifier newLineNotifier = ValueNotifier(0); + // Notifies when a new line is rendered with the position of the new line. + @internal + final ValueNotifier newLinePositionNotifier = + ValueNotifier(0); + double _currentLinePosition = 0.0; TextBoxConfig get boxConfig => _boxConfig; @@ -304,7 +311,8 @@ class TextBoxComponent extends TextComponent { textElement.render(canvas, position); if (position.y > _currentLinePosition) { _currentLinePosition = position.y; - newLineCallback?.call(_currentLinePosition + _lineHeight); + newLineNotifier.value = newLineNotifier.value + 1; + newLinePositionNotifier.value = _currentLinePosition + _lineHeight; } charCount += lines[i].length; } diff --git a/packages/flame/test/components/scroll_text_box_component_test.dart b/packages/flame/test/components/scroll_text_box_component_test.dart index 0992c3cd68d..35259333a62 100644 --- a/packages/flame/test/components/scroll_text_box_component_test.dart +++ b/packages/flame/test/components/scroll_text_box_component_test.dart @@ -72,6 +72,25 @@ functionality properly adjusts the text position.''', expect(innerScrollComponent.position.y, lessThan(0)); }, ); + + testWithFlameGame('Text notifies if a new line is added', (game) async { + int newLineCount = 0; + final scrollComponent = ScrollTextBoxComponent( + size: Vector2(50, 50), + text: '''This +test +has +five +lines.''', + ); + expect(scrollComponent.newLineNotifier.value, equals(0)); + + scrollComponent.newLineNotifier.addListener(() { + newLineCount++; + }); + await game.ensureAdd(scrollComponent); + expect(newLineCount, equals(5)); + }); }); } diff --git a/packages/flame/test/components/text_box_component_test.dart b/packages/flame/test/components/text_box_component_test.dart index 518f560bb52..3c034f69680 100644 --- a/packages/flame/test/components/text_box_component_test.dart +++ b/packages/flame/test/components/text_box_component_test.dart @@ -121,6 +121,27 @@ void main() { }, ); + testWithFlameGame( + 'TextBoxComponent notifies if a new line is added and requires space', + (game) async { + double lineSize = 0; + final textBoxComponent = TextBoxComponent( + size: Vector2(50, 50), + text: '''This +test +has +five +lines.''', + ); + expect(textBoxComponent.newLinePositionNotifier.value, equals(0)); + + textBoxComponent.newLinePositionNotifier.addListener(() { + lineSize += textBoxComponent.newLinePositionNotifier.value; + }); + await game.ensureAdd(textBoxComponent); + expect(lineSize, greaterThan(0)); + }); + testGolden( 'Alignment options', (game) async { From 77577ee0d5eab4d628e88f68b0a9a3dadbc39218 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Thu, 28 Mar 2024 15:39:12 +0100 Subject: [PATCH 08/11] Move onComplete callback from ScrollTextBoxComponent to TextBoxComponent --- doc/flame/rendering/text_rendering.md | 6 ++--- .../components/scroll_text_box_component.dart | 6 +---- .../src/components/text_box_component.dart | 15 ++++++++++-- .../components/text_box_component_test.dart | 23 +++++++++++++++++++ 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/doc/flame/rendering/text_rendering.md b/doc/flame/rendering/text_rendering.md index 9b140b6f7f1..e77ac6af80b 100644 --- a/doc/flame/rendering/text_rendering.md +++ b/doc/flame/rendering/text_rendering.md @@ -10,10 +10,10 @@ components: - `TextComponent` for rendering a single line of text - `TextBoxComponent` for bounding multi-line text within a sized box, including the possibility of a -typing effect. You can use the `newLineNotifier` to be notified when a new line is added. +typing effect. You can use the `newLineNotifier` to be notified when a new line is added. Use the +`onComplete` callback to get notified when the text is completely printed. - `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding scrolling -capability when the text exceeds the boundaries of the enclosing box. Use the `onComplete` callback -to get notified when the text is completely printed. +capability when the text exceeds the boundaries of the enclosing box. All components are showcased in diff --git a/packages/flame/lib/src/components/scroll_text_box_component.dart b/packages/flame/lib/src/components/scroll_text_box_component.dart index 22152e5a57b..159e7f27bff 100644 --- a/packages/flame/lib/src/components/scroll_text_box_component.dart +++ b/packages/flame/lib/src/components/scroll_text_box_component.dart @@ -114,9 +114,6 @@ class _ScrollTextBoxComponent extends TextBoxComponent late ScrollTextBoxComponent _owner; - /// Callback function to be executed after all text is displayed. - void Function()? onComplete; - bool _isOnCompleteExecuted = false; _ScrollTextBoxComponent({ @@ -128,7 +125,7 @@ class _ScrollTextBoxComponent extends TextBoxComponent super.position, super.scale, double super.angle = 0.0, - this.onComplete, + super.onComplete, }) : super( text: text ?? '', textRenderer: textRenderer ?? TextPaint(), @@ -151,7 +148,6 @@ class _ScrollTextBoxComponent extends TextBoxComponent if (!_isOnCompleteExecuted && finished) { _isOnCompleteExecuted = true; scrollBoundsY = clipComponent.size.y - size.y; - onComplete?.call(); } super.update(dt); diff --git a/packages/flame/lib/src/components/text_box_component.dart b/packages/flame/lib/src/components/text_box_component.dart index 722ade928fe..0b2938af4ec 100644 --- a/packages/flame/lib/src/components/text_box_component.dart +++ b/packages/flame/lib/src/components/text_box_component.dart @@ -88,6 +88,10 @@ class TextBoxComponent extends TextComponent { ValueNotifier(0); double _currentLinePosition = 0.0; + bool _isOnCompleteExecuted = false; + + /// Callback function to be executed after all text is displayed. + void Function()? onComplete; TextBoxConfig get boxConfig => _boxConfig; double get lineHeight => _lineHeight; @@ -105,6 +109,7 @@ class TextBoxComponent extends TextComponent { super.anchor, super.children, super.priority, + this.onComplete, super.key, }) : _boxConfig = boxConfig ?? const TextBoxConfig(), _fixedSize = size != null, @@ -347,8 +352,14 @@ class TextBoxComponent extends TextComponent { } _previousChar = currentChar; - if (_boxConfig.dismissDelay != null && finished) { - removeFromParent(); + if (finished) { + if (!_isOnCompleteExecuted) { + _isOnCompleteExecuted = true; + onComplete?.call(); + } + if (_boxConfig.dismissDelay != null) { + removeFromParent(); + } } } diff --git a/packages/flame/test/components/text_box_component_test.dart b/packages/flame/test/components/text_box_component_test.dart index 3c034f69680..fcd80a10e7e 100644 --- a/packages/flame/test/components/text_box_component_test.dart +++ b/packages/flame/test/components/text_box_component_test.dart @@ -5,6 +5,9 @@ import 'package:flame/components.dart'; import 'package:flame/palette.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; + +import 'scroll_text_box_component_test.dart'; void main() { group('TextBoxComponent', () { @@ -121,6 +124,26 @@ void main() { }, ); + testWithFlameGame( + 'onComplete is called when no scrolling is required', + (game) async { + final onComplete = MockOnCompleteCallback(); + + when(onComplete).thenReturn(null); + + final component = ScrollTextBoxComponent( + size: Vector2(200, 100), + text: 'Short text', + onComplete: onComplete, + ); + await game.ensureAdd(component); + + game.update(0.1); + + verify(onComplete).called(1); + }, + ); + testWithFlameGame( 'TextBoxComponent notifies if a new line is added and requires space', (game) async { From c87e96d0892499bbf6bd34e37b09c3202bdc445a Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Thu, 28 Mar 2024 15:45:29 +0100 Subject: [PATCH 09/11] Update markdown description for TextRendering Correct test variable declaration --- doc/flame/rendering/text_rendering.md | 6 +++--- .../test/components/scroll_text_box_component_test.dart | 2 +- packages/flame/test/components/text_box_component_test.dart | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/flame/rendering/text_rendering.md b/doc/flame/rendering/text_rendering.md index e77ac6af80b..32e73ab8ae9 100644 --- a/doc/flame/rendering/text_rendering.md +++ b/doc/flame/rendering/text_rendering.md @@ -11,9 +11,9 @@ components: - `TextComponent` for rendering a single line of text - `TextBoxComponent` for bounding multi-line text within a sized box, including the possibility of a typing effect. You can use the `newLineNotifier` to be notified when a new line is added. Use the -`onComplete` callback to get notified when the text is completely printed. -- `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding scrolling -capability when the text exceeds the boundaries of the enclosing box. +`onComplete` callback to execute a function when the text is completely printed. +- `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding vertical +scrolling capability when the text exceeds the boundaries of the enclosing box. All components are showcased in diff --git a/packages/flame/test/components/scroll_text_box_component_test.dart b/packages/flame/test/components/scroll_text_box_component_test.dart index 35259333a62..ef83aec181a 100644 --- a/packages/flame/test/components/scroll_text_box_component_test.dart +++ b/packages/flame/test/components/scroll_text_box_component_test.dart @@ -74,7 +74,7 @@ functionality properly adjusts the text position.''', ); testWithFlameGame('Text notifies if a new line is added', (game) async { - int newLineCount = 0; + var newLineCount = 0; final scrollComponent = ScrollTextBoxComponent( size: Vector2(50, 50), text: '''This diff --git a/packages/flame/test/components/text_box_component_test.dart b/packages/flame/test/components/text_box_component_test.dart index fcd80a10e7e..db323d953fe 100644 --- a/packages/flame/test/components/text_box_component_test.dart +++ b/packages/flame/test/components/text_box_component_test.dart @@ -147,7 +147,7 @@ void main() { testWithFlameGame( 'TextBoxComponent notifies if a new line is added and requires space', (game) async { - double lineSize = 0; + var lineSize = 0.0; final textBoxComponent = TextBoxComponent( size: Vector2(50, 50), text: '''This From b3640e53fcef523f9e731c25ec705d360527bc05 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Thu, 28 Mar 2024 16:02:52 +0100 Subject: [PATCH 10/11] Correct markdown issues --- doc/flame/rendering/text_rendering.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/flame/rendering/text_rendering.md b/doc/flame/rendering/text_rendering.md index 32e73ab8ae9..a42b52ba0c1 100644 --- a/doc/flame/rendering/text_rendering.md +++ b/doc/flame/rendering/text_rendering.md @@ -10,10 +10,10 @@ components: - `TextComponent` for rendering a single line of text - `TextBoxComponent` for bounding multi-line text within a sized box, including the possibility of a -typing effect. You can use the `newLineNotifier` to be notified when a new line is added. Use the -`onComplete` callback to execute a function when the text is completely printed. -- `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding vertical -scrolling capability when the text exceeds the boundaries of the enclosing box. +typing effect. You can use the `newLineNotifier` to be notified when a new line is added. Use the +`onComplete` callback to execute a function when the text is completely printed. +- `ScrollTextBoxComponent` enhances the functionality of `TextBoxComponent` by adding vertical +scrolling capability when the text exceeds the boundaries of the enclosing box. All components are showcased in From ed6ecaabd670405143d91d603d35467d747e1700 Mon Sep 17 00:00:00 2001 From: Kurt Laabs Date: Thu, 28 Mar 2024 17:12:50 +0100 Subject: [PATCH 11/11] Refactor ScrollTextBoxComponent and TextBoxComponent --- .../flame/lib/src/components/scroll_text_box_component.dart | 6 ++---- packages/flame/lib/src/components/text_box_component.dart | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/flame/lib/src/components/scroll_text_box_component.dart b/packages/flame/lib/src/components/scroll_text_box_component.dart index 159e7f27bff..c8e26efdaee 100644 --- a/packages/flame/lib/src/components/scroll_text_box_component.dart +++ b/packages/flame/lib/src/components/scroll_text_box_component.dart @@ -16,9 +16,7 @@ import 'package:flutter/painting.dart'; /// capabilities. class ScrollTextBoxComponent extends PositionComponent { late final _ScrollTextBoxComponent _scrollTextBoxComponent; - late final ValueNotifier _newLineNotifier; - - ValueNotifier get newLineNotifier => _newLineNotifier; + late final ValueNotifier newLineNotifier; /// Constructor for [ScrollTextBoxComponent]. /// - [size]: Specifies the size of the text box. @@ -75,7 +73,7 @@ class ScrollTextBoxComponent extends PositionComponent { pixelRatio: pixelRatio, onComplete: onComplete, ); - _newLineNotifier = _scrollTextBoxComponent.newLineNotifier; + newLineNotifier = _scrollTextBoxComponent.newLineNotifier; _scrollTextBoxComponent.setOwnerComponent = this; // Integrates the [ClipComponent] for managing diff --git a/packages/flame/lib/src/components/text_box_component.dart b/packages/flame/lib/src/components/text_box_component.dart index 0b2938af4ec..7aece0d0e4d 100644 --- a/packages/flame/lib/src/components/text_box_component.dart +++ b/packages/flame/lib/src/components/text_box_component.dart @@ -82,6 +82,7 @@ class TextBoxComponent extends TextComponent { /// Notifies when a new line is rendered. final ValueNotifier newLineNotifier = ValueNotifier(0); + // Notifies when a new line is rendered with the position of the new line. @internal final ValueNotifier newLinePositionNotifier =