fyne-io / fyne

Cross platform GUI toolkit in Go inspired by Material Design
https://fyne.io/
Other
24.68k stars 1.37k forks source link

Propose new raster scroll/zoom widget #123

Open gmlewis opened 5 years ago

gmlewis commented 5 years ago

On the #fyne Slack channel @andydotxyz asked me to write up a list of wants for purposes of discussion.

For context, I come from a background of writing Engineering Design Automation (EDA) tools for chip design and would like to use fyne as a playground for some ideas I have. I stumbled across fyne recently and threw together a simple prototype (that needs some serious performance optimization) that can be tried out here: https://github.com/gmlewis/go-gerber/tree/master/examples/bifilar-coil with go run main.go -view -n 20.

The canvas.NewRaster turns out to be a fantastic way to render complex objects (although my quadtree needs serious help right now).

Additionally, I would like to see the following things supported on a canvas.Image:

I hope this makes sense. Basically, with the above features, fyne could be used to make 3D apps and all sorts of EDA/CAD-like tools.

Oh, and while I have a wish-list platform, making it easier to manage a complex 2D or 3D scene would be greatly appreciated, although might be beyond the scope of this request. :smile:

niaow commented 5 years ago

One idea would be to replace the PixelColor with a func(width int, height int) image.Image.

andydotxyz commented 5 years ago

Are the scroll events here with the intention of zooming? If you're talking about pan (simple scroll) the description doesn't make sense.

Also - in this example what does "cursor" mean?

I think that rather than adding this to the canvas.Raster we should consider this a future widget. Canvas elements don't really handle callbacks in this way - but I think this would still fulfil your requirements.

gmlewis commented 5 years ago

Yes, I would most likely use scroll events for quickly zooming.

The mouse drag would most likely be used for panning... but you could equally use mouse drag for zoom or rotate, or all three with various mouse-button modifiers. Think of Maya or Blender or any other desktop 3D application.

andydotxyz commented 5 years ago

Thanks. I see what you mean now. However - in the 2nd item why would you move the cursor? Zooming on a spot under the cursor should smoothly continue whilst leaving the cursor where it already is on screen?

gmlewis commented 5 years ago

Great question... I had never seen this until I ran gerbview ( http://docs.kicad-pcb.org/5.0.2/en/gerbview/gerbview.html ).

By moving the cursor to the center immediately on the first mouse scroll event (after first detecting the exact mouse location)... you can do two things at once... center the design (on that initial location) and move the mouse to the center, then subsequent scroll events will zoom in on the design at the exact spot that was originally "requested" yet keeps it centered in the viewport as you continue to scroll in. I thought this was genius but it can only be accomplished if the app can move the mouse to the center on the first scroll event.

If you want, I can try to put a demo video together to show this in action.

andydotxyz commented 5 years ago

That does assume that the user wants to zoom in on the centre. I’m quite strongly against allowing apps to manipulate the mouse position - in fact I’d be surprised if all desktops allowed us to do such a thing!

gmlewis commented 5 years ago

@andydotxyz - I just thought of an alternative solution to this (without the app having the ability to move the mouse position).

I could use a 'c' keyboard shortcut to first re-center the design on the point where the cursor is currently pointing (which would mean that I would need to immediately query the current pointer/cursor/mouse location)... following by mouse scrollwheel to zoom. It would be a two-step process but much cleaner from an architectural point-of-view.

andydotxyz commented 5 years ago

That makes sense. I imagine that querying the pointer location would need to be a desktop extension, but it should be doable...

gmlewis commented 5 years ago

For #139:

andydotxyz commented 5 years ago

The first is available to widgets through the Scrollable interface I think?

andydotxyz commented 5 years ago

Do you think this could be retitled "Add widget.ScrollableRaster" perhaps? These sorts of event handlers won't be added to canvas primitives but I agree that it would be good to add what you've described.

gmlewis commented 5 years ago

widget.ScrollableRaster handles the first case, but doesn't fully address the "drag events" case, does it? Additionally, ScrollableRaster sounds like panning, whereas the intent of this request is to use the scroll events in an unusual way (e.g. "zooming")... and the "drag" events could be used for 3D rotation or scaling, for example.

andydotxyz commented 5 years ago

I guess there is a big difference between 2D and 3D so probably need different threads. Not sure about doing some built-in “unusual” interactions. If this is to be custom then maybe we should keep it out of the main API. We do need to expose drag events which should be in 1.1...

andydotxyz commented 5 years ago

Added #141 to track the move events.

Keeping this open but renaming