Schwusch / widget_arrows

Draw arrows between widgets in Flutter
https://pub.dev/packages/widget_arrows
MIT License
145 stars 14 forks source link

need way to support non-global coordinate space, by using 'ancestor' in <RenderBox>.localToGlobal(ancestor:) #5

Closed nezoat closed 1 year ago

nezoat commented 4 years ago

Hi. When using ArrowContainer() in a non global coordinate space such as in the detail view of a tablet in landscape with a master/detail view, the arrows are drawn in global coordinate space which results in offset arrows by the amount of the width of the master view. In the 'widget_arrows.dart' in the Paint() method, please see these two lines:

    final startGlobalOffset = start.localToGlobal(Offset.zero);
    final endGlobalOffset = end.localToGlobal(Offset.zero);

The localToGlobal() method has an optional 'ancestor:RenderBox' parameter. If this can be exposed through ArrowContainer, any custom coordinate space RenderBox can be provided, which solves the issue. Hope this helps, thank you!

Schwusch commented 4 years ago

Hi @nezoat! I am not sure I understand the use case, would you mind expanding a bit on how to retrieve the ancestor? Would it be an argument to ArrowContainer or retrieved automatically? Would the RenderBox be the actual argument, or should the argument be a Widget, from which the renderbox is extracted?

nezoat commented 4 years ago

The localToGlobal can take an optional 'ancestor' parameter of type RenderObject. The RenderObject is obtained from the BuildContext, such as 'context.findRenderObject()'

I think the ideal way to handle it would be to use the BuildContext in the ArrowContainer and call findRenderObject() on it and save to a member variable. Then pass this RenderObject to the localToGlobal(ancestor:) method in your Paint() method. No additional argument to ArrowContainer necessary this way, and coordinate space should be automatically calculated correctly no matter where the ArrowContainer is placed in chain of ancestor/parent widgets.

sdoshi983 commented 3 years ago

Dear @nezoat,

I implemented the things you said. But the problem still persist!

IMG-20201226-WA0005

IMG-20201226-WA0004

In case I have missed or misunderstood something, then would be pleased to have a light on it!

The localToGlobal can take an optional 'ancestor' parameter of type RenderObject. The RenderObject is obtained from the BuildContext, such as 'context.findRenderObject()'

I think the ideal way to handle it would be to use the BuildContext in the ArrowContainer and call findRenderObject() on it and save to a member variable. Then pass this RenderObject to the localToGlobal(ancestor:) method in your Paint() method. No additional argument to ArrowContainer necessary this way, and coordinate space should be automatically calculated correctly no matter where the ArrowContainer is placed in chain of ancestor/parent widgets.

nezoat commented 3 years ago

I don't see any problems with what you posted, that's pretty much what I'm doing and it's working for me. All I can suggest is to double check that the RenderObject you're passing into _ArrowPainter() is actually making it to localToGlobal() as expected, since I can't see that part of the code from the screenshots. Outside of that, you'll just have to experiment with the contexts involved with the localToGlobal, because that what causes the arrow to get drawn in the unexpected locations.

Schwusch commented 1 year ago

I just released version 0.4.0 that might fix the problem. I'll close the issue for now, but if the problem persists I can reopen.