errorgen/dialog.go

166 lines
3.1 KiB
Go

package main
import (
"fmt"
"net/url"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
)
// Dialog settings for an individual Error Message popup.
type Dialog struct {
Icon Icon
Title string
Message string
Cancel string
Buttons []*Button
}
// Button settings.
type Button struct {
Label string
Default bool
Disabled bool
// Very custom stuff.
OpenURL string
}
// NewDialog returns the default dialog.
func NewDialog() Dialog {
return Dialog{
Icon: icons[DefaultIcon],
Title: DefaultTitle,
Message: DefaultMessage,
Buttons: []*Button{},
}
}
func (d Dialog) Show(app fyne.App) {
// Validate and set defaults.
if d.Title == "" {
d.Title = DefaultTitle
}
if d.Message == "" {
d.Message = DefaultMessage
}
if d.Icon.Empty() {
d.Icon = icons[DefaultIcon]
}
// If no buttons have text, set a default button.
var hasButtons bool
for _, btn := range d.Buttons {
if btn.Label != "" {
hasButtons = true
break
}
}
if !hasButtons {
d.Buttons = []*Button{
{
Label: "Ok",
},
}
}
// Find the default button.
var defaultButton *Button
for _, btn := range d.Buttons {
if btn.Default {
defaultButton = btn
break
}
}
if defaultButton == nil {
d.Buttons[0].Default = true
defaultButton = d.Buttons[0]
}
// Create the dialog window.
var w fyne.Window
if app != nil {
w = app.NewWindow(d.Title)
} else {
w = fyne.CurrentApp().NewWindow(d.Title)
}
w.SetIcon(d.Icon)
w.CenterOnScreen()
// Icon + Message row.
icon := canvas.NewImageFromResource(d.Icon)
icon.FillMode = canvas.ImageFillOriginal
icon.SetMinSize(fyne.NewSize(32, 32))
message := widget.NewLabel(d.Message)
messageRow := container.New(layout.NewHBoxLayout(), layout.NewSpacer(), icon, message, layout.NewSpacer())
// After clicked handler for buttons.
onClick := func() {
if MainWindow != nil {
MainWindow.Show()
}
w.Close()
}
// Close window (cancel) handler.
w.SetOnClosed(func() {
if d.Cancel != "" {
fmt.Print(d.Cancel)
}
onClick()
})
// Keyboard shortcuts Return & Escape.
w.Canvas().SetOnTypedKey(func(key *fyne.KeyEvent) {
if key.Name == fyne.KeyEnter || key.Name == fyne.KeyReturn {
d.Cancel = ""
fmt.Print(defaultButton.Label)
w.Close()
} else if key.Name == fyne.KeyEscape {
w.Close()
}
})
// Buttons
var buttons = []fyne.CanvasObject{
layout.NewSpacer(),
}
for _, b := range d.Buttons {
b := b
if b.Label == "" {
continue
}
button := widget.NewButton(b.Label, func() {
d.Cancel = ""
fmt.Print(b.Label)
onClick()
// Opening a URL?
if b.OpenURL != "" {
if url, err := url.Parse(b.OpenURL); err == nil {
fyne.CurrentApp().OpenURL(url)
}
}
})
if b.Disabled {
button.Disable()
}
if b.Default {
button.Importance = widget.HighImportance
}
buttons = append(buttons, button, layout.NewSpacer())
}
buttonRow := container.New(layout.NewHBoxLayout(), buttons...)
vbox := container.New(layout.NewVBoxLayout(), messageRow, buttonRow)
w.SetContent(container.New(layout.NewPaddedLayout(), vbox))
w.Show()
}