297 lines
5.6 KiB
Go
297 lines
5.6 KiB
Go
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/data/binding"
|
|
"fyne.io/fyne/v2/dialog"
|
|
"fyne.io/fyne/v2/widget"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type DialogName string
|
|
type DialogKind string
|
|
|
|
type OnConfirmFn func(bool, error, ...interface{})
|
|
type NewDialogFn func(DialogName, DialogKind, fyne.Window, OnConfirmFn, ...binding.DataItem) Dialog
|
|
|
|
const (
|
|
DlgGeneric DialogKind = "Generic"
|
|
)
|
|
|
|
type Dialog interface {
|
|
View
|
|
|
|
Window() fyne.Window
|
|
View() View
|
|
|
|
SetInitialFocusItem(focusItem fyne.Focusable)
|
|
|
|
Show(parent ...fyne.Window)
|
|
OnClose(bool)
|
|
|
|
DialogName() DialogName
|
|
DialogKind() DialogKind
|
|
OnConfirmFn() OnConfirmFn
|
|
}
|
|
|
|
type BaseDialog struct {
|
|
id string
|
|
concreteDialog Dialog
|
|
dlgName DialogName
|
|
dlgKind DialogKind
|
|
dlg dialog.Dialog
|
|
window fyne.Window
|
|
onConfirm OnConfirmFn
|
|
CanvasObj fyne.CanvasObject
|
|
Data binding.DataItem
|
|
focusItem fyne.Focusable
|
|
}
|
|
|
|
func NewBaseDialog(
|
|
concreteDialog Dialog,
|
|
name DialogName,
|
|
kind DialogKind,
|
|
parent fyne.Window,
|
|
confirm OnConfirmFn,
|
|
) *BaseDialog {
|
|
return &BaseDialog{
|
|
id: uuid.NewString(),
|
|
concreteDialog: concreteDialog,
|
|
dlgName: name,
|
|
dlgKind: kind,
|
|
window: parent,
|
|
onConfirm: confirm,
|
|
}
|
|
}
|
|
|
|
func NewBaseDialogWithData(
|
|
concreteDialog Dialog,
|
|
name DialogName,
|
|
kind DialogKind,
|
|
parent fyne.Window,
|
|
confirm OnConfirmFn,
|
|
data binding.DataItem,
|
|
) *BaseDialog {
|
|
return &BaseDialog{
|
|
id: uuid.NewString(),
|
|
concreteDialog: concreteDialog,
|
|
dlgName: name,
|
|
dlgKind: kind,
|
|
window: parent,
|
|
onConfirm: confirm,
|
|
Data: data,
|
|
}
|
|
}
|
|
|
|
func (d BaseDialog) Window() fyne.Window {
|
|
return d.window
|
|
}
|
|
|
|
func (d *BaseDialog) View() View {
|
|
return d
|
|
}
|
|
|
|
func (d BaseDialog) Equals(other View) bool {
|
|
return d.id == other.ID()
|
|
}
|
|
|
|
func (d *BaseDialog) SetInitialFocusItem(focusItem fyne.Focusable) {
|
|
d.focusItem = focusItem
|
|
}
|
|
|
|
func (d BaseDialog) DialogName() DialogName {
|
|
return d.dlgName
|
|
}
|
|
|
|
func (d BaseDialog) DialogKind() DialogKind {
|
|
return d.dlgKind
|
|
}
|
|
|
|
func (d BaseDialog) OnConfirmFn() OnConfirmFn {
|
|
return d.onConfirm
|
|
}
|
|
|
|
func (d *BaseDialog) Show(parent ...fyne.Window) {
|
|
d.concreteDialog.OnShow()
|
|
d.dlg = dialog.NewCustomConfirm(
|
|
d.concreteDialog.Title(),
|
|
"OK", "Cancel",
|
|
d.concreteDialog.Initialize(),
|
|
d.concreteDialog.OnClose,
|
|
d.window,
|
|
)
|
|
d.dlg.Show()
|
|
d.dlg.Resize(fyne.NewSize(640, 480))
|
|
if d.focusItem != nil {
|
|
window := d.window
|
|
if parent != nil {
|
|
window = parent[0]
|
|
}
|
|
window.Canvas().Focus(d.focusItem)
|
|
}
|
|
}
|
|
|
|
func (d BaseDialog) ID() string {
|
|
return d.id
|
|
}
|
|
|
|
func (d *BaseDialog) SetID(id string) {
|
|
d.id = id
|
|
}
|
|
|
|
func (d BaseDialog) Title() string {
|
|
return ""
|
|
}
|
|
|
|
func (d *BaseDialog) Initialize() fyne.CanvasObject {
|
|
return d.CanvasObj
|
|
}
|
|
|
|
func (d *BaseDialog) Refresh() {
|
|
if d.CanvasObj != nil {
|
|
d.CanvasObj.Refresh()
|
|
}
|
|
}
|
|
|
|
func (d *BaseDialog) OnShow() {
|
|
LogWindowEvent(d, OnShow)
|
|
}
|
|
|
|
func (d *BaseDialog) OnHide() {
|
|
LogWindowEvent(d, OnHide)
|
|
}
|
|
|
|
func (d *BaseDialog) OnClose(confirmed bool) {
|
|
LogWindowEventMessage(d, OnClose, fmt.Sprintf("confirmed: %v", confirmed))
|
|
d.OnHide()
|
|
}
|
|
|
|
type FormDialogItemsFn func() []*widget.FormItem
|
|
|
|
type FormDialog struct {
|
|
*BaseDialog
|
|
|
|
confirmLabel string
|
|
dismissLabel string
|
|
|
|
itemsFn FormDialogItemsFn
|
|
items []*widget.FormItem
|
|
}
|
|
|
|
func NewFormDialog(
|
|
concreteDialog Dialog,
|
|
name DialogName,
|
|
kind DialogKind,
|
|
parent fyne.Window,
|
|
confirm OnConfirmFn,
|
|
itemsFn FormDialogItemsFn,
|
|
) *FormDialog {
|
|
return &FormDialog{
|
|
BaseDialog: NewBaseDialog(concreteDialog, name, kind, parent, confirm),
|
|
itemsFn: itemsFn,
|
|
confirmLabel: "OK",
|
|
dismissLabel: "Cancel",
|
|
}
|
|
}
|
|
|
|
func NewformDialogWithData(
|
|
concreteDialog Dialog,
|
|
name DialogName,
|
|
kind DialogKind,
|
|
parent fyne.Window,
|
|
confirm OnConfirmFn,
|
|
itemsFn FormDialogItemsFn,
|
|
data binding.DataItem,
|
|
) *FormDialog {
|
|
return &FormDialog{
|
|
BaseDialog: NewBaseDialogWithData(concreteDialog, name, kind, parent, confirm, data),
|
|
itemsFn: itemsFn,
|
|
confirmLabel: "OK",
|
|
dismissLabel: "Cancel",
|
|
}
|
|
}
|
|
|
|
func (d *FormDialog) SetButtonLabels(
|
|
confirm string,
|
|
dismiss string,
|
|
) {
|
|
d.confirmLabel = confirm
|
|
d.dismissLabel = dismiss
|
|
}
|
|
|
|
func (d *FormDialog) Show(parent ...fyne.Window) {
|
|
d.items = d.itemsFn()
|
|
|
|
d.concreteDialog.OnShow()
|
|
d.dlg = dialog.NewForm(
|
|
d.concreteDialog.Title(),
|
|
d.confirmLabel,
|
|
d.dismissLabel,
|
|
d.items,
|
|
d.concreteDialog.OnClose,
|
|
d.window,
|
|
)
|
|
d.dlg.Show()
|
|
d.dlg.Resize(fyne.NewSize(640, 480))
|
|
if d.focusItem != nil {
|
|
window := d.window
|
|
if parent != nil {
|
|
window = parent[0]
|
|
}
|
|
window.Canvas().Focus(d.focusItem)
|
|
}
|
|
}
|
|
|
|
func (d *FormDialog) Refresh() {
|
|
for _, itm := range d.items {
|
|
itm.Widget.Refresh()
|
|
}
|
|
}
|
|
|
|
var dialogCatalog map[DialogName]map[DialogKind]NewDialogFn
|
|
|
|
func RegisterDialog(name DialogName, kind DialogKind, fn NewDialogFn) {
|
|
if dialogCatalog == nil {
|
|
dialogCatalog = make(map[DialogName]map[DialogKind]NewDialogFn)
|
|
}
|
|
if _, ok := dialogCatalog[name]; !ok {
|
|
dialogCatalog[name] = make(map[DialogKind]NewDialogFn)
|
|
}
|
|
dialogCatalog[name][kind] = fn
|
|
}
|
|
|
|
func NewDialog(
|
|
name DialogName, kind DialogKind,
|
|
parent fyne.Window,
|
|
confirm OnConfirmFn,
|
|
) Dialog {
|
|
if dialogCatalog == nil {
|
|
return nil
|
|
}
|
|
if kindCatalog, ok := dialogCatalog[name]; ok {
|
|
if fn, ok := kindCatalog[kind]; ok {
|
|
return fn(name, kind, parent, confirm)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func NewDialogWithData(
|
|
name DialogName, kind DialogKind,
|
|
parent fyne.Window,
|
|
confirm OnConfirmFn,
|
|
data binding.DataItem,
|
|
) Dialog {
|
|
if dialogCatalog == nil {
|
|
return nil
|
|
}
|
|
if kindCatalog, ok := dialogCatalog[name]; ok {
|
|
if fn, ok := kindCatalog[kind]; ok {
|
|
return fn(name, kind, parent, confirm, data)
|
|
}
|
|
}
|
|
return nil
|
|
}
|