fyne-io / fyne

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

Support more graphic elements the Canvas object #856

Open ajstarks opened 4 years ago

ajstarks commented 4 years ago

Is your feature request related to a problem? Please describe:

The Canvas Object has a limited number of graphical elements

Is it possible to construct a solution with the existing API?

Not elegantly. Though drawing arcs, elipses with another toolkit to an image.Image could then be rendered into the UI using canvas.Image or canvas.Raster.

Describe the solution you'd like to see:

The Canvas module should support more graphical elements: (each element may be independently fillled and stroked with a color.RGBA)

  1. Bezier curves (at least quadratic, possibly cubic)
    // curve beginning at (x1, y1), control point at (x2, y2), end point at (x3, y3)
    Bezier(x1, y1, x2, y2, x3, y3)
  2. Polygons
    // Make a polygon using coordinates in x and y float64 slices (minimum length=3)
    Polygon(x, y)

    3; Ellipses

    // Ellipse centered at (x, y), with width (w), height (h)
    // if w == h, make a circle
    Ellipse(x, y, w, h)
  3. Elliptical and Circular Arcs
    // Arc centered at (x, y), with dimensions at (w,h)
    // stroked between angle a1 and angle a2, in degrees)
    // if w==h make a circular arc
    Arc(x, y, w, h, a1, a2)
ababo commented 4 years ago

Yep, really need an ellipse now, would be very nice to have.

andydotxyz commented 4 years ago

Contributions welcome ;) Joking aside the core team are prioritising canvas elements that help build the widgets, and elipse has not come up. You can still draw an elipse to an image in memory then show it as an image or raster canvas object...

ababo commented 4 years ago

If I was a part of the core team I would introduce ellipses instead of circles from the beginning. Indeed having an ellipse defined by its wrapping rectangle (hello Resize()) looks more consistent. If you need a circle just make width equal to height.

dp1140a commented 3 years ago

Another approach would be to wrap another "canvas" (like the canvas from tfriedel6/canvas) and embed that in the fyne Canvas. Its lower hanging fruit, enables the HTML5 Canvas API and abstracts a "drawing" canvas form the UI canvas. I would love to help contribute this. However I'm pretty new to Fyne. Would this be extending the Canvas or creating a new Widget?

andydotxyz commented 3 years ago

@dp1140a you can already embed tfriedel6/canvas into Fyne I think. If you use their "Software backend" then it outputs a standard Image. You can then embed that in a canvas using canvas.NewImageFromImage.

In our current implementation a fyne.Container is sort of a canvas as it can contain any of the canvas primitives. container.NewWithoutLayout behaves very much like a canvas as it does not try to rearrange elements based on a layout.

dp1140a commented 3 years ago

That would still not solve the interactive part. I have seen other issues here asking about some interactive primitives for the canvas. I tried creating a new widget that wrapped tfriedel6/canvas but couldnt get it working. So I'll still +1 for a "Widget" or a "whosit" or a primitive that would implement the HTML5 Canvas APi and be interactive (clickable/draggable/etc). Having this would open up a realm of possibilities on what we could do; like make games etc...

andydotxyz commented 3 years ago

Wiht our API design, the canvas is for drawing and the widgets handle interaction - it allows us to keep logic an visuals separate.

There are various games made already - I don't think that adding HTML5 is a blocker for that. Of course if it were implemented as a widget then an interactive canvas could be done. Perhaps something for the fyne-x project?

andydotxyz commented 3 years ago

As per #2146 there is also the request for:

charlesdaniels commented 3 years ago

As far as prior art goes, I would cite Tk as having a good canvas implementation, although it fills the role of fc/chart more than what Fyne calls a canvas. Because most of the Tk references on the internet suck, the following is reproduced from Tcl and the Tk Toolkit 2/e, John K. Ousterhout, & Ken Jones §23.1 pp. 433.

  • rectangle - drawn as an outline or a filled area; you can specify the outline color, outline width, fill color, and fill stipple pattern.
  • oval - for circles and ellipses, with the same attributes as rectangles.
  • line - consisting of one or more connected segments, a width, a color, a stiple pattern, and several other attributes such as whether to miter or round the corners between segments and whether or not to draw arrowheads at the ends of the line.
  • Bézier curves - line items with an additional -smooth attribute specifying how Bézier cubic splines should be drawn instead of straight segments.
  • polygon - consisting of three or more points, a fill color, and a stipple pattern. As with line items, you can use the -smooth attribute to specify that the outline of the polygon should be a Bézier curve instead of a collection straight segments.
  • arc - drawn in any of several styles such as a pie wedge or a section of a circle. You can specify attributes such as the arc's angular range, outline witdth, outline color, fill color, and fill stipple.
  • text - consisting of one or more lines drawn in a single font. You can select a font, color, stipple pattern, justification mode, and line length.
  • bitmap - consisting of a bitmap name, background color, and foreground color.
  • image - consisting of a photo or bitmap image created using the Tk image create command or any of the Tk image extensions.
  • window - an embedded widget of any kind, in which case the canvas acts as a geometry manager for the widget. The canvas reference documentation and command syntax use the term window to refer to these embedded widgets.

I'm not claiming we should implement all of these, or implement them exactly as described here. However this is probably a good outline of features that make up a good canvas, and Tk has seen a lot of use and is quite mature.

Jacalz commented 1 week ago

I think it would be wiser and easier to divide this up into separate issues for bézier curves, polygons, ellipses and arcs. It would make it easier to keep track of them and close them as they are implemented.