zenity/zenity.go

243 lines
5.9 KiB
Go
Raw Normal View History

2020-01-23 06:44:28 -05:00
// Package zenity provides cross-platform access to simple dialogs that interact
// graphically with the user.
//
// It is inspired by, and closely follows the API of, the zenity program, which
// it uses to provide the functionality on various Unixes. See:
//
2020-01-26 11:04:49 -05:00
// https://help.gnome.org/users/zenity/stable/
2020-01-23 06:44:28 -05:00
//
// This package does not require cgo, and it does not impose any threading or
// initialization requirements.
2020-01-04 22:21:39 -05:00
package zenity
2020-01-28 07:46:43 -05:00
import (
"context"
"image/color"
2022-03-28 15:22:39 -04:00
"time"
2021-04-30 14:05:49 -04:00
2024-07-10 00:06:01 -04:00
"git.bigun.dev/evan/zenity/internal/zenutil"
2020-01-28 07:46:43 -05:00
)
2020-01-18 07:40:16 -05:00
2022-12-14 19:26:34 -05:00
func ptr[T any](v T) *T { return &v }
2020-01-06 07:01:51 -05:00
2021-04-29 11:05:28 -04:00
// ErrCanceled is returned when the cancel button is pressed,
// or window functions are used to close the dialog.
2021-04-30 14:19:14 -04:00
const ErrCanceled = zenutil.ErrCanceled
2021-04-29 11:05:28 -04:00
// ErrExtraButton is returned when the extra button is pressed.
2021-04-30 14:19:14 -04:00
const ErrExtraButton = zenutil.ErrExtraButton
2021-04-29 11:05:28 -04:00
// ErrUnsupported is returned when a combination of options is not supported.
2021-04-30 14:19:14 -04:00
const ErrUnsupported = zenutil.ErrUnsupported
2021-04-30 14:05:49 -04:00
2022-12-14 18:53:30 -05:00
// IsAvailable reports whether dependencies of the package are installed.
// It always returns true on Windows and macOS.
func IsAvailable() bool {
return isAvailable()
}
2020-01-04 22:21:39 -05:00
type options struct {
// General options
2021-05-11 09:51:56 -04:00
title *string
2024-07-09 23:47:11 -04:00
alwaysOnTop bool
2021-05-11 09:51:56 -04:00
width uint
height uint
okLabel *string
cancelLabel *string
extraButton *string
defaultCancel bool
2022-05-17 11:18:12 -04:00
icon any
2022-05-18 09:48:09 -04:00
windowIcon any
2022-06-02 07:24:24 -04:00
attach any
modal bool
2022-12-19 14:49:05 -05:00
display string
class string
name string
2021-05-11 09:51:56 -04:00
// Message options
noWrap bool
ellipsize bool
2021-03-05 10:14:30 -05:00
// Entry options
entryText string
hideText bool
2021-03-05 21:07:00 -05:00
username bool
2021-03-05 10:14:30 -05:00
2021-04-07 09:16:35 -04:00
// List options
2022-07-28 20:16:15 -04:00
listKind listKind
2022-12-19 14:49:05 -05:00
midSearch bool
2021-04-07 09:16:35 -04:00
disallowEmpty bool
defaultItems []string
2021-04-11 22:02:21 -04:00
// Calendar options
2022-03-28 22:05:46 -04:00
time *time.Time
2021-04-11 22:02:21 -04:00
2020-01-04 22:21:39 -05:00
// File selection options
2020-01-24 07:52:45 -05:00
directory bool
confirmOverwrite bool
confirmCreate bool
showHidden bool
2021-03-05 10:14:30 -05:00
filename string
2021-04-11 22:59:08 -04:00
fileFilters FileFilters
2020-01-04 22:21:39 -05:00
2020-01-18 07:40:16 -05:00
// Color selection options
2020-01-24 07:52:45 -05:00
color color.Color
showPalette bool
2020-01-18 07:40:16 -05:00
2021-04-25 13:34:56 -04:00
// Progress indication options
maxValue int
noCancel bool
2023-08-03 07:55:59 -04:00
autoClose bool
2021-04-25 13:34:56 -04:00
timeRemaining bool
2020-01-28 07:46:43 -05:00
// Context for timeout
ctx context.Context
2020-01-04 22:21:39 -05:00
}
2020-01-23 06:44:28 -05:00
// An Option is an argument passed to dialog functions to customize their
// behavior.
2020-01-24 07:52:45 -05:00
type Option interface {
apply(*options)
}
type funcOption func(*options)
func (f funcOption) apply(o *options) { f(o) }
2020-01-04 22:21:39 -05:00
2020-01-24 07:52:45 -05:00
func applyOptions(options []Option) (res options) {
2020-01-04 22:21:39 -05:00
for _, o := range options {
2020-01-24 07:52:45 -05:00
o.apply(&res)
2020-01-04 22:21:39 -05:00
}
return
}
2020-01-23 06:44:28 -05:00
// Title returns an Option to set the dialog title.
2020-01-04 22:21:39 -05:00
func Title(title string) Option {
2021-03-03 21:52:05 -05:00
return funcOption(func(o *options) { o.title = &title })
2020-01-04 22:21:39 -05:00
}
2020-01-27 10:42:43 -05:00
2024-07-09 23:47:11 -04:00
// AlwaysOnTop returns an Option to set the dialog to be always on top (Windows only)..
func AlwaysOnTop(alwaysOnTop bool) Option {
return funcOption(func(o *options) {
o.alwaysOnTop = alwaysOnTop
})
}
2021-02-12 09:24:13 -05:00
// Width returns an Option to set the dialog width (Unix only).
func Width(width uint) Option {
return funcOption(func(o *options) {
o.width = width
})
}
// Height returns an Option to set the dialog height (Unix only).
func Height(height uint) Option {
return funcOption(func(o *options) {
o.height = height
})
}
2021-03-05 10:14:30 -05:00
// OKLabel returns an Option to set the label of the OK button.
func OKLabel(ok string) Option {
return funcOption(func(o *options) { o.okLabel = &ok })
}
// CancelLabel returns an Option to set the label of the Cancel button.
func CancelLabel(cancel string) Option {
return funcOption(func(o *options) { o.cancelLabel = &cancel })
}
2022-05-02 06:22:53 -04:00
// ExtraButton returns an Option to add one extra button.
2021-03-05 10:14:30 -05:00
func ExtraButton(extra string) Option {
return funcOption(func(o *options) { o.extraButton = &extra })
}
2022-05-17 10:36:00 -04:00
// DefaultCancel returns an Option to give the Cancel button focus by default.
func DefaultCancel() Option {
return funcOption(func(o *options) { o.defaultCancel = true })
}
2022-05-04 18:22:19 -04:00
// DialogIcon is an Option that sets the dialog icon.
2020-01-27 10:42:43 -05:00
type DialogIcon int
2022-05-05 08:04:27 -04:00
func (i DialogIcon) apply(o *options) {
o.icon = i
}
2021-05-11 09:58:04 -04:00
2020-01-30 09:14:42 -05:00
// The stock dialog icons.
2020-01-27 10:42:43 -05:00
const (
2022-05-17 11:18:12 -04:00
ErrorIcon DialogIcon = iota
2020-01-27 10:42:43 -05:00
WarningIcon
InfoIcon
QuestionIcon
2021-03-05 10:14:30 -05:00
PasswordIcon
2021-03-04 08:06:49 -05:00
NoIcon
2020-01-27 10:42:43 -05:00
)
// Icon returns an Option to set the dialog icon.
2022-05-04 18:22:19 -04:00
//
2022-05-17 11:18:12 -04:00
// Icon accepts a DialogIcon, or a string.
2022-07-26 12:02:42 -04:00
// The string can be a GTK icon name (Unix), or a file path (Windows and macOS).
// Supported file formats depend on the plaftorm, but PNG should be cross-platform.
2022-05-17 11:18:12 -04:00
func Icon(icon any) Option {
switch icon.(type) {
2022-06-04 08:09:58 -04:00
case DialogIcon, string:
2022-05-17 11:18:12 -04:00
default:
panic("interface conversion: expected string or DialogIcon")
}
return funcOption(func(o *options) { o.icon = icon })
}
2020-01-28 07:46:43 -05:00
2022-06-02 07:24:24 -04:00
// WindowIcon returns an Option to set the window icon.
2022-05-18 09:48:09 -04:00
//
2022-07-26 12:02:42 -04:00
// WindowIcon accepts a DialogIcon, or a string file path.
// Supported file formats depend on the plaftorm, but PNG should be cross-platform.
2022-05-18 09:48:09 -04:00
func WindowIcon(icon any) Option {
switch icon.(type) {
2022-06-04 08:09:58 -04:00
case DialogIcon, string:
2022-05-18 09:48:09 -04:00
default:
panic("interface conversion: expected string or DialogIcon")
}
return funcOption(func(o *options) { o.windowIcon = icon })
}
2022-12-14 18:53:30 -05:00
// Attach returns an Option to set the parent window to attach to.
//
// Attach accepts:
// - a window id (int) on Unix
// - a window handle (~uintptr) on Windows
// - an application name (string) or process id (int) on macOS
func Attach(id any) Option {
return attach(id)
}
2022-06-02 07:24:24 -04:00
// Modal returns an Option to set the modal hint.
func Modal() Option {
return funcOption(func(o *options) { o.modal = true })
}
2022-12-19 14:49:05 -05:00
// Display returns an Option to set the X display to use (Unix only).
func Display(display string) Option {
return funcOption(func(o *options) { o.display = display })
}
// ClassHint returns an Option to set the program name and class
// as used by the window manager (Unix only).
func ClassHint(name, class string) Option {
return funcOption(func(o *options) {
if name != "" {
o.name = name
}
if class != "" {
o.class = class
}
})
}
2020-01-29 09:15:21 -05:00
// Context returns an Option to set a Context that can dismiss the dialog.
2020-01-30 09:14:42 -05:00
//
2022-05-02 06:22:53 -04:00
// Dialogs dismissed by ctx return ctx.Err().
2020-01-28 07:46:43 -05:00
func Context(ctx context.Context) Option {
return funcOption(func(o *options) { o.ctx = ctx })
}