package objects import "image" import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo/event" import "git.tebibyte.media/tomo/tomo/theme" import "git.tebibyte.media/tomo/objects/layouts" // DialogKind defines the semantic role of a dialog window. type DialogKind int; const ( DialogInformation DialogKind = iota DialogQuestion DialogWarning DialogError ) // Dialog is a modal dialog window. type Dialog struct { tomo.Window controlRow tomo.ContainerBox } type clickable interface { OnClick (func ()) event.Cookie } // NewDialog creates a new dialog window given a dialog kind. func NewDialog (kind DialogKind, parent tomo.Window, title, message string, options ...tomo.Object) (*Dialog, error) { if title == "" { switch kind { case DialogInformation: title = "Information" case DialogQuestion: title = "Question" case DialogWarning: title = "Warning" case DialogError: title = "Error" } } dialog := &Dialog { } if parent == nil { window, err := tomo.NewWindow(image.Rectangle { }) if err != nil { return nil, err } dialog.Window = window } else { window, err := parent.NewModal(image.Rectangle { }) if err != nil { return nil, err } dialog.Window = window } var iconId theme.Icon switch kind { case DialogInformation: iconId = theme.IconStatusInformation case DialogQuestion: iconId = theme.IconStatusQuestion case DialogWarning: iconId = theme.IconStatusWarning case DialogError: iconId = theme.IconStatusError } dialog.SetTitle(title) icon := NewIcon(iconId, theme.IconSizeLarge) messageText := NewLabel(message) messageText.SetAlign(tomo.AlignStart, tomo.AlignMiddle) for _, option := range options { if option, ok := option.(clickable); ok { option.OnClick(dialog.Close) } } dialog.controlRow = NewInnerContainer(layouts.ContractHorizontal, options...) dialog.controlRow.SetAlign(tomo.AlignEnd, tomo.AlignEnd) dialog.SetRoot(NewOuterContainer ( layouts.NewGrid([]bool { true }, []bool { true, false }), NewInnerContainer(layouts.ContractHorizontal, icon, messageText), dialog.controlRow)) return dialog, nil } // NewDialogOk creates a new dialog window with an OK option. func NewDialogOk (kind DialogKind, parent tomo.Window, title, message string, onOk func ()) (*Dialog, error) { okButton := NewButton("OK") okButton.SetIcon(theme.IconStatusOkay) okButton.OnClick(func () { if onOk != nil { onOk() } }) okButton.SetFocused(true) return NewDialog(kind, parent, title, message, okButton) } // NewDialogOkCancel creates a new dialog window with OK and Cancel options. func NewDialogOkCancel (kind DialogKind, parent tomo.Window, title, message string, onOk func ()) (*Dialog, error) { cancelButton := NewButton("Cancel") cancelButton.SetIcon(theme.IconStatusCancel) okButton := NewButton("OK") okButton.SetIcon(theme.IconStatusOkay) okButton.OnClick(func () { if onOk != nil { onOk() } }) okButton.SetFocused(true) return NewDialog(kind, parent, title, message, cancelButton, okButton) }