andlabs / ui

Platform-native GUI library for Go.
Other
8.33k stars 651 forks source link

Drawing a Point? #258

Open salacryl opened 6 years ago

salacryl commented 6 years ago

Hi,

due to the lack of a function to brush freehand, I tried to draw a single pixel with Lineto, but it crashes unsafe.

Here is the code:

func (t areaHandlerDraw) Draw(a *ui.Area, dp *ui.AreaDrawParams) {

    var brush ui.Brush
    brush.Type = ui.Solid
    var p = ui.NewPath(ui.Winding)
    var sp ui.StrokeParams
    for x := 0; x < pic.Bounds().Max.X; x++ {
        for y := 0; y < pic.Bounds().Max.Y; y++ {

            r, g, b, alpha := pic.At(x, y).RGBA()
            brush.A = float64(alpha)
            brush.R = float64(r)
            brush.G = float64(g)
            brush.B = float64(b)
            //brush.X0 = float64(x)
            //brush.Y0 = float64(y)
            p.NewFigure(float64(x), float64(y))
            p.LineTo(float64(x), float64(y))
            sp.Thickness = 1.0
            dp.Context.Stroke(p, &brush, &sp)
            //dp.Context.Save()
        }
    }

    return
}

Pic is loaded in a function before and declared accessable by all functions.

Greetings Björn

salacryl commented 6 years ago

Got it. My mistake was I tried to reuse the path-variable. This leads to an unsafe exception. Also I had to convert to color-percentage (of course).

It works now. Not all pixel all precisely there, where they should be, but this could be due to the fact, that "NewFigure" and "Lineto" take float (why tho? Those are pixels).

Here is what I get: Image

if it's any interesting, here's the code

code

nilsmartel commented 6 years ago

wow, thanks for showing this, i like to see exactly something like this :)

andlabs commented 6 years ago

You can't draw pixel-perfect art with Area because it does not use a pixel coordinate system. At some point I may introduce facilities to convert between pixels and points, but until then, I'm not sure what to say other than wait for the 0.4 release when proper images will be added.

In all honesty, the big reason why libui doesn't let you edit a path object that has already been closed is because of the Windows implementation, which has a similar restriction. I might add a function MutableCopy or something like that to path to allow building a path over time using the freeform drawing tool that you want to add, but you will have to note that it'd still not be pixel-based.

And it seems like you're trying to add a handwriting system; that would best be provided by the OS, and should be automatic with Entry, EditableCombo, and MultilineEntry. I don't know if it will be automatic when I add text editing events to Area, but it should...

As for your bug, yes, paths are a write-once object. For what you are trying to do, consider using transformation matrices. Also your use of Save is incorrect; Save should be read like PushGraphicsStateOntoAnInternalGraphicsStateStack.

andlabs commented 6 years ago

Note to self: I could probably make Path more flexible on Windows by generating the path objects as needed. GTK+ works this way already.