Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TapUpDetais.globalPosition is incorrect #122

Open
bramp opened this issue Sep 20, 2023 · 1 comment
Open

TapUpDetais.globalPosition is incorrect #122

bramp opened this issue Sep 20, 2023 · 1 comment

Comments

@bramp
Copy link

bramp commented Sep 20, 2023

When running the Storybook with the device frame and panels down the size, the Tap Details globalPosition incorrectly includes the screen outside of the device frame.

For example:

GestureDetector(
  behavior: HitTestBehavior.opaque,
  onTapUp: (details) {
    print('onTapUp ${details.globalPosition}');
  },
  child: const Placeholder(),
)

If you click in the top left corner, you don't get 0,0, but instead ~600,10, because it includes the 600 pixels of panel to the left of the device frame.

This globalPosition should somehow be compensated for the area outside of the device being emulated.

@bramp
Copy link
Author

bramp commented Sep 20, 2023

Ok, I fixed this for myself by creating a widget that can map the offset. This does require a little bit more work, but it keeps my testing simple.

/// Insert TranslatePosition into the widget tree and call
/// TranslatePosition.translate(context, offset) to translate the global offset
/// to a offset from this widget.
class TranslatePosition extends StatelessWidget {
  final Widget child;

  const TranslatePosition({Key? key, required this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    GlobalKey key = GlobalKey();

    return Provider(
      key: key,
      create: (context) {
        final RenderBox box =
            key.currentContext!.findRenderObject() as RenderBox;

        // The top left corner of the TranslatePosition widget.
        return TranslatePositionOffset(box.localToGlobal(Offset.zero));
      },
      child: child,
    );
  }

  static translate(BuildContext context, Offset global) {
    try {
      return global - context.read<TranslatePositionOffset>();
    } on ProviderNullException {
      return global;
    }
  }
}

class TranslatePositionOffset extends Offset {
  TranslatePositionOffset(Offset offset) : super(offset.dx, offset.dy);
}
Storybook(
      wrapperBuilder: (context, child) {
        return TranslatePosition(
          child: child,
        );
      },
GestureDetector(
    behavior: HitTestBehavior.opaque,
    onTapUp: (details) {
        final position = TranslatePosition.translate(context, details.globalPosition);
        print('onTapUp $position');
    }
)

I also looked if there was a easy way to hook into Flutter to change this, but didn't find anything useful. BTW The reason I needed the "global" position, was to work with Overlays, which seem to assume the top-left of the app is 0,0, and there is no conveniant way to get the coordinates of where the Overlay is in global coordinates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant