Skip to content

Commit

Permalink
feat: Align component refactoring (#2767)
Browse files Browse the repository at this point in the history
I suggest changing the child element of the Align component. In this case, the child element is not a required parameter.
Motivation:
Thus, the Align component can be created as a class field.
We can replace the child at any time.
Hello:
I can create a label field on a button and change the label depending on the state of the button.
  • Loading branch information
denisgl7 committed Sep 25, 2023
1 parent be28a44 commit bde34ef
Showing 1 changed file with 51 additions and 19 deletions.
70 changes: 51 additions & 19 deletions packages/flame/lib/src/layout/align_component.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import 'package:flame/src/anchor.dart';
import 'package:flame/src/components/position_component.dart';
import 'package:flame/components.dart';
import 'package:flame/src/effects/provider_interfaces.dart';
import 'package:flutter/widgets.dart';
import 'package:vector_math/vector_math_64.dart';

/// **AlignComponent** is a layout component that positions its child within
/// itself using relative placement. It is similar to Flutter's [Align] widget.
Expand Down Expand Up @@ -55,34 +53,48 @@ class AlignComponent extends PositionComponent {
/// within the current component's bounding box. The child's anchor will also
/// be set to the [alignment], unless [keepChildAnchor] parameter is true.
AlignComponent({
required this.child,
required Anchor alignment,
PositionComponent? child,
Anchor alignment = Anchor.topLeft,
this.widthFactor,
this.heightFactor,
this.keepChildAnchor = false,
}) {
this.alignment = alignment;
add(child);
this.child = child;
}

late Anchor _alignment;
PositionComponent? _child;

/// The component that will be positioned by this component. The [child] will
/// be automatically mounted to the current component.
final PositionComponent child;
PositionComponent? get child => _child;

set child(PositionComponent? value) {
if (_child == value) {
return;
}
if (_child?.parent == this) {
_child?.removeFromParent();
}
_child = value;
_child?.parent = this;
_updateChildAnchor();
_updateChildPosition();
}

late Anchor _alignment;

/// How the [child] will be positioned within the current component.
///
/// Note: unlike Flutter's [Alignment], the top-left corner of the component
/// has relative coordinates `(0, 0)`, while the bottom-right corner has
/// coordinates `(1, 1)`.
Anchor get alignment => _alignment;

set alignment(Anchor value) {
_alignment = value;
if (!keepChildAnchor) {
child.anchor = value;
}
child.position = Vector2(size.x * alignment.x, size.y * alignment.y);
_updateChildAnchor();
_updateChildPosition();
}

/// If `null`, then the component's width will be equal to the width of the
Expand All @@ -96,8 +108,8 @@ class AlignComponent extends PositionComponent {
final double? heightFactor;

/// If `false` (default), then the child's `anchor` will be kept equal to the
/// [alignment] value. If `true`, then the [child] will be allowed to have its
/// own `anchor` value independent from the parent.
/// [alignment] value. If `true`, then the [child] will be allowed to have
/// its own `anchor` value independent from the parent.
final bool keepChildAnchor;

@override
Expand All @@ -115,10 +127,30 @@ class AlignComponent extends PositionComponent {

@override
void onParentResize(Vector2 maxSize) {
super.size = Vector2(
widthFactor == null ? maxSize.x : child.size.x * widthFactor!,
heightFactor == null ? maxSize.y : child.size.y * heightFactor!,
);
child.position = Vector2(size.x * alignment.x, size.y * alignment.y);
if (_child != null) {
super.size = Vector2(
widthFactor == null ? maxSize.x : _child!.size.x * widthFactor!,
heightFactor == null ? maxSize.y : _child!.size.y * heightFactor!,
);
}
_updateChildPosition();
}

@mustCallSuper
@override
void onChildrenChanged(Component child, ChildrenChangeType type) {
if (_child?.parent != this) {
this.child = null;
}
}

void _updateChildPosition() {
_child?.position = Vector2(size.x * alignment.x, size.y * alignment.y);
}

void _updateChildAnchor() {
if (!keepChildAnchor) {
_child?.anchor = _alignment;
}
}
}

0 comments on commit bde34ef

Please sign in to comment.