andlabs / ui

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

Window is black when opened from another window (OSX) #218

Closed xeoncross closed 7 years ago

xeoncross commented 7 years ago

I am opening a confirm window from a button inside another window. However, the new window is completely black and the windows stop responding telling me that the libui must be waiting for something.

What is the correct way to open a window on a button click?

func confirmWindow(title, msg string) bool {
    w := ui.NewWindow("Confirm", 300, 100, true)
    w.SetMargined(true)
    if title != "" {
        w.SetTitle(title)
    }

    c := make(chan bool)

    confirm := ui.NewButton("Ok")
    confirm.OnClicked(func(b *ui.Button) {
        c <- true
    })

    deny := ui.NewButton("Cancel")
    deny.OnClicked(func(b *ui.Button) {
        c <- false
    })

    box := ui.NewHorizontalBox()
    box.SetPadded(true)
    box.Append(confirm, true)
    box.Append(deny, true)

    wrapper := ui.NewVerticalBox()
    wrapper.SetPadded(true)
    wrapper.Append(ui.NewLabel(msg), true)
    wrapper.Append(box, true)
    w.SetChild(wrapper)
    w.Show()

    return <-c
}

Worth noting that a file selector window opens just fine:

    fileButton.OnClicked(func(b *ui.Button) {
        x := ui.OpenFile(ui.NewWindow("Choose a File", 500, 500, true))
        fmt.Println("User chose a file:", x)
    })
xeoncross commented 7 years ago

Solved. I can't hang out inside the OnChange() function. I need to exit the function in order for libui to draw the new window and the return <-c was waiting for the response from the window that wasn't drawn yet.

andlabs commented 7 years ago

The file selector window works fine because it doesn't return until you select a file, and while it's open the system is processing events which allows the rest of the app to draw properly.

What you can do is process the response to the dialog in another goroutine and use the channel to communicate that. For the code you are writing, I need to add more message box types... (that part about processing events causes portability problems that I have no idea how to solve, which is why there aren't more dialogs right now)

xeoncross commented 7 years ago

I just ended up using a callback instead of trying to select on goroutines. Something like this:

func callbackWindow(msg string, callback func()) {
    w := ui.NewWindow("Confirm", 300, 100, true)
    w.SetMargined(true)

    confirm := ui.NewButton("Click me")
    confirm.OnClicked(func(b *ui.Button) {
        w.Destroy()
        callback() // or go callback() depending on what it does
    })

    wrapper := ui.NewVerticalBox()
    wrapper.SetPadded(true)
    wrapper.Append(ui.NewLabel(msg), true)
    wrapper.Append(confirm, false)
    w.SetChild(wrapper)
    w.Show()

}