Improve documentation.
This commit is contained in:
parent
0728bdf5ad
commit
44cd5fa43b
17 changed files with 259 additions and 246 deletions
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/ncruces/zenity?status.svg)](https://godoc.org/github.com/ncruces/zenity)
|
[![GoDoc](https://godoc.org/github.com/ncruces/zenity?status.svg)](https://godoc.org/github.com/ncruces/zenity)
|
||||||
|
|
||||||
This repo includes both a cross-platform Go package providing [Zenity](https://help.gnome.org/users/zenity/)-like dialogs,
|
This repo includes both a cross-platform Go package providing
|
||||||
|
[Zenity](https://help.gnome.org/users/zenity/)-like dialogs
|
||||||
|
(simple dialogs that interact graphically with the user),
|
||||||
as well as a *“port”* of the `zenity` command to both Windows and macOS based on that library.
|
as well as a *“port”* of the `zenity` command to both Windows and macOS based on that library.
|
||||||
|
|
||||||
**This is a work in progress.**
|
**This is a work in progress.**
|
||||||
|
|
22
color.go
Normal file
22
color.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package zenity
|
||||||
|
|
||||||
|
import "image/color"
|
||||||
|
|
||||||
|
// SelectColor displays the color selection dialog.
|
||||||
|
//
|
||||||
|
// Returns nil on cancel.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Color, ShowPalette.
|
||||||
|
func SelectColor(options ...Option) (color.Color, error) {
|
||||||
|
return selectColor(options...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color returns an Option to set the color.
|
||||||
|
func Color(c color.Color) Option {
|
||||||
|
return func(o *options) { o.color = c }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShowPalette returns an Option to show the palette.
|
||||||
|
func ShowPalette() Option {
|
||||||
|
return func(o *options) { o.palette = true }
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/ncruces/zenity/internal/zenutil"
|
"github.com/ncruces/zenity/internal/zenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SelectColor(options ...Option) (color.Color, error) {
|
func selectColor(options ...Option) (color.Color, error) {
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
var data zenutil.Color
|
var data zenutil.Color
|
||||||
|
|
|
@ -9,12 +9,7 @@ import (
|
||||||
"github.com/ncruces/zenity/internal/zenutil"
|
"github.com/ncruces/zenity/internal/zenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Display color selection dialog.
|
func selectColor(options ...Option) (color.Color, error) {
|
||||||
//
|
|
||||||
// Returns nil on cancel.
|
|
||||||
//
|
|
||||||
// Valid options: Title, Color, ShowPalette.
|
|
||||||
func SelectColor(options ...Option) (color.Color, error) {
|
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
args := []string{"--color-selection"}
|
args := []string{"--color-selection"}
|
||||||
|
|
|
@ -20,7 +20,7 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SelectColor(options ...Option) (color.Color, error) {
|
func selectColor(options ...Option) (color.Color, error) {
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
// load custom colors
|
// load custom colors
|
||||||
|
|
81
file.go
81
file.go
|
@ -5,6 +5,87 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SelectFile displays the file selection dialog.
|
||||||
|
//
|
||||||
|
// Returns an empty string on cancel.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Directory, Filename, ShowHidden, FileFilter(s).
|
||||||
|
func SelectFile(options ...Option) (string, error) {
|
||||||
|
return selectFile(options...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectFileMutiple displays the multiple file selection dialog.
|
||||||
|
//
|
||||||
|
// Returns a nil slice on cancel.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Directory, Filename, ShowHidden, FileFilter(s).
|
||||||
|
func SelectFileMutiple(options ...Option) ([]string, error) {
|
||||||
|
return selectFileMutiple(options...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectFileSave displays the save file selection dialog.
|
||||||
|
//
|
||||||
|
// Returns an empty string on cancel.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Filename, ConfirmOverwrite, ConfirmCreate, ShowHidden,
|
||||||
|
// FileFilter(s).
|
||||||
|
func SelectFileSave(options ...Option) (string, error) {
|
||||||
|
return selectFileSave(options...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filename returns an Option to set the filename.
|
||||||
|
//
|
||||||
|
// You can specify a file name, a directory path, or both.
|
||||||
|
// Specifying a file name, makes it the default selected file.
|
||||||
|
// Specifying a directory path, makes it the default dialog location.
|
||||||
|
func Filename(filename string) Option {
|
||||||
|
return func(o *options) { o.filename = filename }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directory returns an Option to activate directory-only selection.
|
||||||
|
func Directory() Option {
|
||||||
|
return func(o *options) { o.directory = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfirmOverwrite returns an Option to confirm file selection if filename
|
||||||
|
// already exists.
|
||||||
|
func ConfirmOverwrite() Option {
|
||||||
|
return func(o *options) { o.overwrite = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfirmCreate returns an Option to confirm file selection if filename does
|
||||||
|
// not yet exist (Windows only).
|
||||||
|
func ConfirmCreate() Option {
|
||||||
|
return func(o *options) { o.create = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShowHidden returns an Option to show hidden files (Windows and macOS only).
|
||||||
|
func ShowHidden() Option {
|
||||||
|
return func(o *options) { o.hidden = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileFilter encapsulates a filename filter.
|
||||||
|
//
|
||||||
|
// macOS hides filename filters from the user,
|
||||||
|
// and only supports filtering by extension (or "type").
|
||||||
|
type FileFilter struct {
|
||||||
|
Name string // display string that describes the filter (optional)
|
||||||
|
Patterns []string // filter patterns for the display string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build returns an Option to set a filename filter.
|
||||||
|
func (f FileFilter) Build() Option {
|
||||||
|
return func(o *options) { o.filters = append(o.filters, f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileFilters is a list of filename filters.
|
||||||
|
type FileFilters []FileFilter
|
||||||
|
|
||||||
|
// Build returns an Option to set filename filters.
|
||||||
|
func (f FileFilters) Build() Option {
|
||||||
|
return func(o *options) { o.filters = append(o.filters, f...) }
|
||||||
|
}
|
||||||
|
|
||||||
func splitDirAndName(path string) (dir, name string) {
|
func splitDirAndName(path string) (dir, name string) {
|
||||||
path = filepath.Clean(path)
|
path = filepath.Clean(path)
|
||||||
fi, err := os.Stat(path)
|
fi, err := os.Stat(path)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/ncruces/zenity/internal/zenutil"
|
"github.com/ncruces/zenity/internal/zenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SelectFile(options ...Option) (string, error) {
|
func selectFile(options ...Option) (string, error) {
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
data := zenutil.File{
|
data := zenutil.File{
|
||||||
|
@ -35,7 +35,7 @@ func SelectFile(options ...Option) (string, error) {
|
||||||
return string(out), nil
|
return string(out), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SelectFileMutiple(options ...Option) ([]string, error) {
|
func selectFileMutiple(options ...Option) ([]string, error) {
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
data := zenutil.File{
|
data := zenutil.File{
|
||||||
|
@ -68,7 +68,7 @@ func SelectFileMutiple(options ...Option) ([]string, error) {
|
||||||
return strings.Split(string(out), zenutil.Separator), nil
|
return strings.Split(string(out), zenutil.Separator), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SelectFileSave(options ...Option) (string, error) {
|
func selectFileSave(options ...Option) (string, error) {
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
data := zenutil.File{
|
data := zenutil.File{
|
||||||
|
|
21
file_unix.go
21
file_unix.go
|
@ -9,12 +9,7 @@ import (
|
||||||
"github.com/ncruces/zenity/internal/zenutil"
|
"github.com/ncruces/zenity/internal/zenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Display file selection dialog.
|
func selectFile(options ...Option) (string, error) {
|
||||||
//
|
|
||||||
// Returns an empty string on cancel.
|
|
||||||
//
|
|
||||||
// Valid options: Title, Directory, Filename, ShowHidden, FileFilter(s).
|
|
||||||
func SelectFile(options ...Option) (string, error) {
|
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
args := []string{"--file-selection"}
|
args := []string{"--file-selection"}
|
||||||
|
@ -42,12 +37,7 @@ func SelectFile(options ...Option) (string, error) {
|
||||||
return string(out), nil
|
return string(out), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display multiple file selection dialog.
|
func selectFileMutiple(options ...Option) ([]string, error) {
|
||||||
//
|
|
||||||
// Returns a nil slice on cancel.
|
|
||||||
//
|
|
||||||
// Valid options: Title, Directory, Filename, ShowHidden, FileFilter(s).
|
|
||||||
func SelectFileMutiple(options ...Option) ([]string, error) {
|
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
args := []string{"--file-selection", "--multiple", "--separator", zenutil.Separator}
|
args := []string{"--file-selection", "--multiple", "--separator", zenutil.Separator}
|
||||||
|
@ -75,12 +65,7 @@ func SelectFileMutiple(options ...Option) ([]string, error) {
|
||||||
return strings.Split(string(out), zenutil.Separator), nil
|
return strings.Split(string(out), zenutil.Separator), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display save file selection dialog.
|
func selectFileSave(options ...Option) (string, error) {
|
||||||
//
|
|
||||||
// Returns an empty string on cancel.
|
|
||||||
//
|
|
||||||
// Valid options: Title, Filename, ConfirmOverwrite, ConfirmCreate, ShowHidden, FileFilter(s).
|
|
||||||
func SelectFileSave(options ...Option) (string, error) {
|
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
args := []string{"--file-selection", "--save"}
|
args := []string{"--file-selection", "--save"}
|
||||||
|
|
|
@ -17,7 +17,7 @@ var (
|
||||||
shCreateItemFromParsingName = shell32.NewProc("SHCreateItemFromParsingName")
|
shCreateItemFromParsingName = shell32.NewProc("SHCreateItemFromParsingName")
|
||||||
)
|
)
|
||||||
|
|
||||||
func SelectFile(options ...Option) (string, error) {
|
func selectFile(options ...Option) (string, error) {
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
if opts.directory {
|
if opts.directory {
|
||||||
res, _, err := pickFolders(opts, false)
|
res, _, err := pickFolders(opts, false)
|
||||||
|
@ -53,7 +53,7 @@ func SelectFile(options ...Option) (string, error) {
|
||||||
return syscall.UTF16ToString(res[:]), nil
|
return syscall.UTF16ToString(res[:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SelectFileMutiple(options ...Option) ([]string, error) {
|
func selectFileMutiple(options ...Option) ([]string, error) {
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
if opts.directory {
|
if opts.directory {
|
||||||
_, res, err := pickFolders(opts, true)
|
_, res, err := pickFolders(opts, true)
|
||||||
|
@ -114,7 +114,7 @@ func SelectFileMutiple(options ...Option) ([]string, error) {
|
||||||
return split, nil
|
return split, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SelectFileSave(options ...Option) (string, error) {
|
func selectFileSave(options ...Option) (string, error) {
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
if opts.directory {
|
if opts.directory {
|
||||||
res, _, err := pickFolders(opts, false)
|
res, _, err := pickFolders(opts, false)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// +build !windows,!darwin
|
// +build !windows,!darwin
|
||||||
|
|
||||||
|
// Package zenutil is internal. DO NOT USE.
|
||||||
package zenutil
|
package zenutil
|
||||||
|
|
||||||
const LineBreak = "\n"
|
const LineBreak = "\n"
|
||||||
|
|
|
@ -13,7 +13,7 @@ var scripts = template.Must(template.New("").Funcs(template.FuncMap{"json": func
|
||||||
{{define "color" -}}tell application (path to frontmost application as text)
|
{{define "color" -}}tell application (path to frontmost application as text)
|
||||||
activate
|
activate
|
||||||
{{if .Color -}}
|
{{if .Color -}}
|
||||||
set c to choose color default color { {{index .Color 0}}, {{index .Color 1}}, {{index .Color 2}} }
|
set c to choose color default color { {{index .Color 0}},{{index .Color 1}},{{index .Color 2}} }
|
||||||
{{else -}}
|
{{else -}}
|
||||||
set c to choose color
|
set c to choose color
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
tell application (path to frontmost application as text)
|
tell application (path to frontmost application as text)
|
||||||
activate
|
activate
|
||||||
{{if .Color -}}
|
{{if .Color -}}
|
||||||
set c to choose color default color { {{index .Color 0}}, {{index .Color 1}}, {{index .Color 2}} }
|
set c to choose color default color { {{index .Color 0}},{{index .Color 1}},{{index .Color 2}} }
|
||||||
{{else -}}
|
{{else -}}
|
||||||
set c to choose color
|
set c to choose color
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
97
msg.go
Normal file
97
msg.go
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
package zenity
|
||||||
|
|
||||||
|
// ErrExtraButton is returned by dialog functions when the extra button is
|
||||||
|
// pressed.
|
||||||
|
const ErrExtraButton = constError("Extra button pressed.")
|
||||||
|
|
||||||
|
// Question displays the question dialog.
|
||||||
|
//
|
||||||
|
// Returns true on OK, false on Cancel, or ErrExtraButton.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Icon, OKLabel, CancelLabel, ExtraButton, NoWrap,
|
||||||
|
// Ellipsize, DefaultCancel.
|
||||||
|
func Question(text string, options ...Option) (bool, error) {
|
||||||
|
return message(questionKind, text, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info displays the info dialog.
|
||||||
|
//
|
||||||
|
// Returns true on OK, false on dismiss, or ErrExtraButton.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize.
|
||||||
|
func Info(text string, options ...Option) (bool, error) {
|
||||||
|
return message(infoKind, text, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning displays the warning dialog.
|
||||||
|
//
|
||||||
|
// Returns true on OK, false on dismiss, or ErrExtraButton.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize.
|
||||||
|
func Warning(text string, options ...Option) (bool, error) {
|
||||||
|
return message(warningKind, text, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error displays the error dialog.
|
||||||
|
//
|
||||||
|
// Returns true on OK, false on dismiss, or ErrExtraButton.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize.
|
||||||
|
func Error(text string, options ...Option) (bool, error) {
|
||||||
|
return message(errorKind, text, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
type messageKind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
questionKind messageKind = iota
|
||||||
|
infoKind
|
||||||
|
warningKind
|
||||||
|
errorKind
|
||||||
|
)
|
||||||
|
|
||||||
|
// MessageIcon is the enumeration for message dialog icons.
|
||||||
|
type MessageIcon int
|
||||||
|
|
||||||
|
// Icons for
|
||||||
|
const (
|
||||||
|
ErrorIcon MessageIcon = iota + 1
|
||||||
|
WarningIcon
|
||||||
|
InfoIcon
|
||||||
|
QuestionIcon
|
||||||
|
)
|
||||||
|
|
||||||
|
// Icon returns an Option to set the dialog icon.
|
||||||
|
func Icon(icon MessageIcon) Option {
|
||||||
|
return func(o *options) { o.icon = icon }
|
||||||
|
}
|
||||||
|
|
||||||
|
// OKLabel returns an Option to set the label of the OK button.
|
||||||
|
func OKLabel(ok string) Option {
|
||||||
|
return func(o *options) { o.ok = ok }
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelLabel returns an Option to set the label of the Cancel button.
|
||||||
|
func CancelLabel(cancel string) Option {
|
||||||
|
return func(o *options) { o.cancel = cancel }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtraButton returns an Option to add an extra button.
|
||||||
|
func ExtraButton(extra string) Option {
|
||||||
|
return func(o *options) { o.extra = extra }
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoWrap returns an Option to disable enable text wrapping.
|
||||||
|
func NoWrap() Option {
|
||||||
|
return func(o *options) { o.nowrap = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ellipsize returns an Option to enable ellipsizing in the dialog text.
|
||||||
|
func Ellipsize() Option {
|
||||||
|
return func(o *options) { o.ellipsize = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultCancel returns an Option to give Cancel button focus by default.
|
||||||
|
func DefaultCancel() Option {
|
||||||
|
return func(o *options) { o.defcancel = true }
|
||||||
|
}
|
|
@ -6,26 +6,10 @@ import (
|
||||||
"github.com/ncruces/zenity/internal/zenutil"
|
"github.com/ncruces/zenity/internal/zenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Question(text string, options ...Option) (bool, error) {
|
func message(kind messageKind, text string, options []Option) (bool, error) {
|
||||||
return message(0, text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Info(text string, options ...Option) (bool, error) {
|
|
||||||
return message(1, text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Warning(text string, options ...Option) (bool, error) {
|
|
||||||
return message(2, text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Error(text string, options ...Option) (bool, error) {
|
|
||||||
return message(3, text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func message(typ int, text string, options []Option) (bool, error) {
|
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
data := zenutil.Msg{Text: text}
|
data := zenutil.Msg{Text: text}
|
||||||
dialog := typ == 0 || opts.icon != 0
|
dialog := kind == questionKind || opts.icon != 0
|
||||||
|
|
||||||
if dialog {
|
if dialog {
|
||||||
data.Operation = "displayDialog"
|
data.Operation = "displayDialog"
|
||||||
|
@ -46,17 +30,17 @@ func message(typ int, text string, options []Option) (bool, error) {
|
||||||
data.Text = opts.title
|
data.Text = opts.title
|
||||||
}
|
}
|
||||||
|
|
||||||
switch typ {
|
switch kind {
|
||||||
case 1:
|
case infoKind:
|
||||||
data.As = "informational"
|
data.As = "informational"
|
||||||
case 2:
|
case warningKind:
|
||||||
data.As = "warning"
|
data.As = "warning"
|
||||||
case 3:
|
case errorKind:
|
||||||
data.As = "critical"
|
data.As = "critical"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if typ != 0 {
|
if kind != questionKind {
|
||||||
if dialog {
|
if dialog {
|
||||||
opts.ok = "OK"
|
opts.ok = "OK"
|
||||||
}
|
}
|
||||||
|
@ -69,7 +53,7 @@ func message(typ int, text string, options []Option) (bool, error) {
|
||||||
if opts.cancel == "" {
|
if opts.cancel == "" {
|
||||||
opts.cancel = "Cancel"
|
opts.cancel = "Cancel"
|
||||||
}
|
}
|
||||||
if typ == 0 {
|
if kind == questionKind {
|
||||||
if opts.extra == "" {
|
if opts.extra == "" {
|
||||||
data.Buttons = []string{opts.cancel, opts.ok}
|
data.Buttons = []string{opts.cancel, opts.ok}
|
||||||
data.Default = 2
|
data.Default = 2
|
||||||
|
|
51
msg_unix.go
51
msg_unix.go
|
@ -8,47 +8,20 @@ import (
|
||||||
"github.com/ncruces/zenity/internal/zenutil"
|
"github.com/ncruces/zenity/internal/zenutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Display question dialog.
|
func message(kind messageKind, text string, options []Option) (bool, error) {
|
||||||
//
|
|
||||||
// Returns true on OK, false on Cancel, or ErrExtraButton.
|
|
||||||
//
|
|
||||||
// Valid options: Title, Icon, OKLabel, CancelLabel, ExtraButton, NoWrap,
|
|
||||||
// Ellipsize, DefaultCancel.
|
|
||||||
func Question(text string, options ...Option) (bool, error) {
|
|
||||||
return message("--question", text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display info dialog.
|
|
||||||
//
|
|
||||||
// Returns true on OK, false on dismiss, or ErrExtraButton.
|
|
||||||
//
|
|
||||||
// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize.
|
|
||||||
func Info(text string, options ...Option) (bool, error) {
|
|
||||||
return message("--info", text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display warning dialog.
|
|
||||||
//
|
|
||||||
// Returns true on OK, false on dismiss, or ErrExtraButton.
|
|
||||||
//
|
|
||||||
// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize.
|
|
||||||
func Warning(text string, options ...Option) (bool, error) {
|
|
||||||
return message("--warning", text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display error dialog.
|
|
||||||
//
|
|
||||||
// Returns true on OK, false on dismiss, or ErrExtraButton.
|
|
||||||
//
|
|
||||||
// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize.
|
|
||||||
func Error(text string, options ...Option) (bool, error) {
|
|
||||||
return message("--error", text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func message(arg, text string, options []Option) (bool, error) {
|
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
args := []string{arg}
|
var args []string
|
||||||
|
switch kind {
|
||||||
|
case questionKind:
|
||||||
|
args = append(args, "--question")
|
||||||
|
case infoKind:
|
||||||
|
args = append(args, "--info")
|
||||||
|
case warningKind:
|
||||||
|
args = append(args, "--warning")
|
||||||
|
case errorKind:
|
||||||
|
args = append(args, "--error")
|
||||||
|
}
|
||||||
if text != "" {
|
if text != "" {
|
||||||
args = append(args, "--text", text, "--no-markup")
|
args = append(args, "--text", text, "--no-markup")
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,31 +10,15 @@ var (
|
||||||
messageBox = user32.NewProc("MessageBoxW")
|
messageBox = user32.NewProc("MessageBoxW")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Question(text string, options ...Option) (bool, error) {
|
func message(kind messageKind, text string, options []Option) (bool, error) {
|
||||||
return message(0, text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Info(text string, options ...Option) (bool, error) {
|
|
||||||
return message(1, text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Warning(text string, options ...Option) (bool, error) {
|
|
||||||
return message(2, text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Error(text string, options ...Option) (bool, error) {
|
|
||||||
return message(3, text, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func message(typ int, text string, options []Option) (bool, error) {
|
|
||||||
opts := optsParse(options)
|
opts := optsParse(options)
|
||||||
|
|
||||||
var flags, caption uintptr
|
var flags, caption uintptr
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case typ == 0 && opts.extra != "":
|
case kind == questionKind && opts.extra != "":
|
||||||
flags |= 0x3 // MB_YESNOCANCEL
|
flags |= 0x3 // MB_YESNOCANCEL
|
||||||
case typ == 0 || opts.extra != "":
|
case kind == questionKind || opts.extra != "":
|
||||||
flags |= 0x1 // MB_OKCANCEL
|
flags |= 0x1 // MB_OKCANCEL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +33,7 @@ func message(typ int, text string, options []Option) (bool, error) {
|
||||||
flags |= 0x40 // MB_ICONINFORMATION
|
flags |= 0x40 // MB_ICONINFORMATION
|
||||||
}
|
}
|
||||||
|
|
||||||
if typ == 0 && opts.defcancel {
|
if kind == questionKind && opts.defcancel {
|
||||||
if opts.extra == "" {
|
if opts.extra == "" {
|
||||||
flags |= 0x100 // MB_DEFBUTTON2
|
flags |= 0x100 // MB_DEFBUTTON2
|
||||||
} else {
|
} else {
|
||||||
|
@ -65,7 +49,7 @@ func message(typ int, text string, options []Option) (bool, error) {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
hook, err := hookMessageLabels(typ, opts)
|
hook, err := hookMessageLabels(kind, opts)
|
||||||
if hook == 0 {
|
if hook == 0 {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -79,7 +63,7 @@ func message(typ int, text string, options []Option) (bool, error) {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if n == 7 || n == 2 && typ != 0 { // IDNO
|
if n == 7 || n == 2 && kind != questionKind { // IDNO
|
||||||
return false, ErrExtraButton
|
return false, ErrExtraButton
|
||||||
}
|
}
|
||||||
if n == 1 || n == 6 { // IDOK, IDYES
|
if n == 1 || n == 6 { // IDOK, IDYES
|
||||||
|
@ -88,7 +72,7 @@ func message(typ int, text string, options []Option) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hookMessageLabels(typ int, opts options) (hook uintptr, err error) {
|
func hookMessageLabels(kind messageKind, opts options) (hook uintptr, err error) {
|
||||||
tid, _, _ := getCurrentThreadId.Call()
|
tid, _, _ := getCurrentThreadId.Call()
|
||||||
hook, _, err = setWindowsHookEx.Call(12, // WH_CALLWNDPROCRET
|
hook, _, err = setWindowsHookEx.Call(12, // WH_CALLWNDPROCRET
|
||||||
syscall.NewCallback(func(code int, wparam uintptr, lparam *_CWPRETSTRUCT) uintptr {
|
syscall.NewCallback(func(code int, wparam uintptr, lparam *_CWPRETSTRUCT) uintptr {
|
||||||
|
@ -107,7 +91,7 @@ func hookMessageLabels(typ int, opts options) (hook uintptr, err error) {
|
||||||
case 1, 6: // IDOK, IDYES
|
case 1, 6: // IDOK, IDYES
|
||||||
text = opts.ok
|
text = opts.ok
|
||||||
case 2: // IDCANCEL
|
case 2: // IDCANCEL
|
||||||
if typ == 0 {
|
if kind == questionKind {
|
||||||
text = opts.cancel
|
text = opts.cancel
|
||||||
} else if opts.extra != "" {
|
} else if opts.extra != "" {
|
||||||
text = opts.extra
|
text = opts.extra
|
||||||
|
|
137
zenity.go
137
zenity.go
|
@ -1,19 +1,21 @@
|
||||||
|
// 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:
|
||||||
|
//
|
||||||
|
// https://help.gnome.org/users/zenity/
|
||||||
|
//
|
||||||
|
// This package does not require cgo, and it does not impose any threading or
|
||||||
|
// initialization requirements.
|
||||||
package zenity
|
package zenity
|
||||||
|
|
||||||
import "image/color"
|
import "image/color"
|
||||||
|
|
||||||
// Errors
|
|
||||||
|
|
||||||
type constError string
|
type constError string
|
||||||
|
|
||||||
func (e constError) Error() string { return string(e) }
|
func (e constError) Error() string { return string(e) }
|
||||||
|
|
||||||
// Message errors
|
|
||||||
|
|
||||||
const ErrExtraButton = constError("Extra button pressed.")
|
|
||||||
|
|
||||||
// Options
|
|
||||||
|
|
||||||
type options struct {
|
type options struct {
|
||||||
// General options
|
// General options
|
||||||
title string
|
title string
|
||||||
|
@ -40,7 +42,8 @@ type options struct {
|
||||||
defcancel bool
|
defcancel bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options are arguments passed to dialog functions to customize their behavior.
|
// An Option is an argument passed to dialog functions to customize their
|
||||||
|
// behavior.
|
||||||
type Option func(*options)
|
type Option func(*options)
|
||||||
|
|
||||||
func optsParse(options []Option) (res options) {
|
func optsParse(options []Option) (res options) {
|
||||||
|
@ -50,121 +53,7 @@ func optsParse(options []Option) (res options) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// General options
|
// Title returns an Option to set the dialog title.
|
||||||
|
|
||||||
// Option to set the dialog title.
|
|
||||||
func Title(title string) Option {
|
func Title(title string) Option {
|
||||||
return func(o *options) { o.title = title }
|
return func(o *options) { o.title = title }
|
||||||
}
|
}
|
||||||
|
|
||||||
// File selection options
|
|
||||||
|
|
||||||
// Option to set the filename.
|
|
||||||
//
|
|
||||||
// You can specify a file name, a directory path, or both.
|
|
||||||
// Specifying a file name, makes it the default selected file.
|
|
||||||
// Specifying a directory path, makes it the default dialog location.
|
|
||||||
func Filename(filename string) Option {
|
|
||||||
return func(o *options) { o.filename = filename }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to activate directory-only selection.
|
|
||||||
func Directory() Option {
|
|
||||||
return func(o *options) { o.directory = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to confirm file selection if filename already exists.
|
|
||||||
func ConfirmOverwrite() Option {
|
|
||||||
return func(o *options) { o.overwrite = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to confirm file selection if filename does not yet exist (Windows only).
|
|
||||||
func ConfirmCreate() Option {
|
|
||||||
return func(o *options) { o.create = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to show hidden files (Windows and macOS only).
|
|
||||||
func ShowHidden() Option {
|
|
||||||
return func(o *options) { o.hidden = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileFilter encapsulates a filename filter.
|
|
||||||
//
|
|
||||||
// macOS hides filename filters from the user,
|
|
||||||
// and only supports filtering by extension (or "type").
|
|
||||||
type FileFilter struct {
|
|
||||||
Name string // display string that describes the filter (optional)
|
|
||||||
Patterns []string // filter patterns for the display string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build option to set a filename filter.
|
|
||||||
func (f FileFilter) Build() Option {
|
|
||||||
return func(o *options) { o.filters = append(o.filters, f) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileFilters is a list of filename filters.
|
|
||||||
type FileFilters []FileFilter
|
|
||||||
|
|
||||||
// Build option to set filename filters.
|
|
||||||
func (f FileFilters) Build() Option {
|
|
||||||
return func(o *options) { o.filters = append(o.filters, f...) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Color selection options
|
|
||||||
|
|
||||||
// Option to set the color.
|
|
||||||
func Color(c color.Color) Option {
|
|
||||||
return func(o *options) { o.color = c }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to show the palette.
|
|
||||||
func ShowPalette() Option {
|
|
||||||
return func(o *options) { o.palette = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message options
|
|
||||||
|
|
||||||
// MessageIcon is the enumeration for message dialog icons.
|
|
||||||
type MessageIcon int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ErrorIcon MessageIcon = iota + 1
|
|
||||||
WarningIcon
|
|
||||||
InfoIcon
|
|
||||||
QuestionIcon
|
|
||||||
)
|
|
||||||
|
|
||||||
// Option to set the dialog icon.
|
|
||||||
func Icon(icon MessageIcon) Option {
|
|
||||||
return func(o *options) { o.icon = icon }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to set the label of the OK button.
|
|
||||||
func OKLabel(ok string) Option {
|
|
||||||
return func(o *options) { o.ok = ok }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to set the label of the Cancel button.
|
|
||||||
func CancelLabel(cancel string) Option {
|
|
||||||
return func(o *options) { o.cancel = cancel }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to add an extra button.
|
|
||||||
func ExtraButton(extra string) Option {
|
|
||||||
return func(o *options) { o.extra = extra }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to disable enable text wrapping.
|
|
||||||
func NoWrap() Option {
|
|
||||||
return func(o *options) { o.nowrap = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to enable ellipsizing in the dialog text.
|
|
||||||
func Ellipsize() Option {
|
|
||||||
return func(o *options) { o.ellipsize = true }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option to give Cancel button focus by default.
|
|
||||||
func DefaultCancel() Option {
|
|
||||||
return func(o *options) { o.defcancel = true }
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue