Skip to content
This repository has been archived by the owner on Jan 19, 2023. It is now read-only.

Commit

Permalink
Pushing events down to all children
Browse files Browse the repository at this point in the history
  • Loading branch information
ericmartineau committed Jan 18, 2021
1 parent 96665ec commit abf15d5
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 21 deletions.
48 changes: 27 additions & 21 deletions lib/fab_circular_menu.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:math';

import 'package:fab_circular_menu/stack_with_all_children_receive_events.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math.dart' as vector;
Expand Down Expand Up @@ -36,7 +37,7 @@ class FabCircularMenu extends StatefulWidget {
FabCircularMenu(
{Key key,
this.buttonKey,
this.alignment = Alignment.bottomRight,
this.alignment = Alignment.bottomCenter,
this.ringColor,
this.ringDiameter,
this.ringWidth,
Expand Down Expand Up @@ -138,19 +139,20 @@ class FabCircularMenuState extends State<FabCircularMenu>
}

return Container(
margin: widget.fabMargin,
// Removes the default FAB margin
transform: widget.removeDefaultFabMargin
? Matrix4.translationValues(16.0, 16.0, 0.0)
: null,
child: Stack(
child: StackWithAllChildrenReceiveEvents(
overflow: Overflow.visible,
alignment: widget.alignment,
children: <Widget>[

// Ring
Transform(
transform:
Matrix4.translationValues(_translationX, _translationY, 0.0)
..scale(_scaleAnimation.value),
Matrix4.translationValues(_translationX, _translationY, 0.0)
..scale(_scaleAnimation.value),
alignment: FractionalOffset.center,
child: OverflowBox(
maxWidth: _ringDiameter,
Expand All @@ -162,22 +164,22 @@ class FabCircularMenuState extends State<FabCircularMenu>
painter: _RingPainter(width: _ringWidth, color: _ringColor),
child: _scaleAnimation.value == 1.0
? Transform.rotate(
angle: (2 * pi) *
_rotateAnimation.value *
_directionX *
_directionY,
child: Container(
child: Stack(
alignment: Alignment.center,
children: widget.children
.asMap()
.map((index, child) => MapEntry(index,
_applyTransformations(child, index)))
.values
.toList(),
),
),
)
angle: (2 * pi) *
_rotateAnimation.value *
_directionX *
_directionY,
child: Container(
child: Stack(
alignment: Alignment.center,
children: widget.children
.asMap()
.map((index, child) => MapEntry(index,
_applyTransformations(child, index)))
.values
.toList(),
),
),
)
: Container(),
),
),
Expand All @@ -186,6 +188,7 @@ class FabCircularMenuState extends State<FabCircularMenu>

// FAB
Container(
margin: widget.fabMargin,
width: widget.fabSize,
height: widget.fabSize,
child: RawMaterialButton(
Expand All @@ -210,6 +213,9 @@ class FabCircularMenuState extends State<FabCircularMenu>
: widget.fabChild),
),
),



],
),
);
Expand Down
92 changes: 92 additions & 0 deletions lib/stack_with_all_children_receive_events.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.dart';

/// Passes all events to all children of the stack. The FAB was having issues
/// where the padding on the button was blocking the circular items on the edge
class StackWithAllChildrenReceiveEvents extends Stack {

StackWithAllChildrenReceiveEvents({
Key key,
AlignmentGeometry alignment = AlignmentDirectional.topStart,
TextDirection textDirection = TextDirection.ltr,
StackFit fit = StackFit.loose,
Overflow overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
Clip clipBehavior = Clip.hardEdge,
}) : super(
key: key,
alignment: alignment,
textDirection: textDirection,
fit: fit,
overflow: overflow,
clipBehavior: clipBehavior,
children: children,
);


@override
RenderStackWithAllChildrenReceiveEvents createRenderObject(BuildContext context) {
return RenderStackWithAllChildrenReceiveEvents(
alignment: alignment,
textDirection: textDirection ?? Directionality.of(context),
fit: fit,
clipBehavior: overflow == Overflow.visible ? Clip.none : clipBehavior,
);
// return RenderStackWithAllChildrenReceiveEvents(
// alignment: alignment,
// textDirection: textDirection ?? Directionality.of(context),
// fit: fit,
// overflow: overflow,
// );
}

@override
void updateRenderObject(BuildContext context, RenderStackWithAllChildrenReceiveEvents renderObject) {
renderObject
..alignment = alignment
..textDirection = textDirection ?? Directionality.of(context)
..fit = fit
..clipBehavior = overflow == Overflow.visible ? Clip.none : clipBehavior;
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
properties.add(EnumProperty<StackFit>('fit', fit));
properties.add(EnumProperty<Overflow>('overflow', overflow));
}

}

class RenderStackWithAllChildrenReceiveEvents extends RenderStack {
RenderStackWithAllChildrenReceiveEvents({
List<RenderBox> children,
AlignmentGeometry alignment = AlignmentDirectional.topStart,
TextDirection textDirection,
StackFit fit = StackFit.loose,
Clip clipBehavior = Clip.hardEdge,
}): super(
alignment: alignment,
textDirection: textDirection,
fit: fit,
clipBehavior: clipBehavior,
);

bool allCdefaultHitTestChildren(HitTestResult result, { Offset position }) {
// the x, y parameters have the top left of the node's box as the origin
RenderBox child = lastChild;
while (child != null) {
final StackParentData childParentData = child.parentData;
child.hitTest(result, position: position - childParentData.offset);
child = childParentData.previousSibling;
}
return false;
}

@override
bool hitTestChildren(HitTestResult result, { Offset position }) {
return allCdefaultHitTestChildren(result, position: position);
}
}

0 comments on commit abf15d5

Please sign in to comment.