List (macOS), see #3.
This commit is contained in:
parent
4e896ffb7a
commit
e0c4c9a88c
9 changed files with 219 additions and 0 deletions
|
@ -36,6 +36,12 @@ app.activate()
|
||||||
var res=app.{{.Operation}}({{json .Options}})
|
var res=app.{{.Operation}}({{json .Options}})
|
||||||
if(Array.isArray(res)){res.join({{json .Separator}})}else{res.toString()}
|
if(Array.isArray(res)){res.join({{json .Separator}})}else{res.toString()}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
{{define "list" -}}
|
||||||
|
var app=Application.currentApplication()
|
||||||
|
app.includeStandardAdditions=true
|
||||||
|
var res=app.chooseFromList({{json .Items}},{{json .Options}})
|
||||||
|
res.join({{json .Separator}})
|
||||||
|
{{- end}}
|
||||||
{{define "notify" -}}
|
{{define "notify" -}}
|
||||||
var app=Application.currentApplication()
|
var app=Application.currentApplication()
|
||||||
app.includeStandardAdditions=true
|
app.includeStandardAdditions=true
|
||||||
|
|
5
internal/zenutil/osascripts/list.gojs
Normal file
5
internal/zenutil/osascripts/list.gojs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
var app = Application.currentApplication()
|
||||||
|
app.includeStandardAdditions = true
|
||||||
|
|
||||||
|
var res = app.chooseFromList({{json .Items}}, {{json .Options}})
|
||||||
|
res.join({{json .Separator}})
|
|
@ -86,6 +86,24 @@ type DialogOptions struct {
|
||||||
Timeout int `json:"givingUpAfter,omitempty"`
|
Timeout int `json:"givingUpAfter,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List is internal.
|
||||||
|
type List struct {
|
||||||
|
Items []string
|
||||||
|
Separator string
|
||||||
|
Options ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListOptions is internal.
|
||||||
|
type ListOptions struct {
|
||||||
|
Title *string `json:"withTitle,omitempty"`
|
||||||
|
Prompt *string `json:"withPrompt,omitempty"`
|
||||||
|
OK *string `json:"okButtonName,omitempty"`
|
||||||
|
Cancel *string `json:"cancelButtonName,omitempty"`
|
||||||
|
Default []string `json:"defaultItems,omitempty"`
|
||||||
|
Multiple bool `json:"multipleSelectionsAllowed,omitempty"`
|
||||||
|
Empty bool `json:"emptySelectionAllowed,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// Notify is internal.
|
// Notify is internal.
|
||||||
type Notify struct {
|
type Notify struct {
|
||||||
Text string
|
Text string
|
||||||
|
|
45
list.go
Normal file
45
list.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package zenity
|
||||||
|
|
||||||
|
// List displays the list dialog.
|
||||||
|
//
|
||||||
|
// Returns false on cancel, or ErrExtraButton.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Width, Height, OKLabel, CancelLabel, ExtraButton,
|
||||||
|
// Icon, DefaultItems, DisallowEmpty.
|
||||||
|
func List(text string, items []string, options ...Option) (string, bool, error) {
|
||||||
|
return list(text, items, applyOptions(options))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListItems displays the list dialog.
|
||||||
|
//
|
||||||
|
// Returns false on cancel, or ErrExtraButton.
|
||||||
|
func ListItems(text string, items ...string) (string, bool, error) {
|
||||||
|
return List(text, items)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMultiple displays the list dialog, allowing multiple rows to be selected.
|
||||||
|
//
|
||||||
|
// Returns a nil slice on cancel, or ErrExtraButton.
|
||||||
|
//
|
||||||
|
// Valid options: Title, Width, Height, OKLabel, CancelLabel, ExtraButton,
|
||||||
|
// Icon, DefaultItems, DisallowEmpty.
|
||||||
|
func ListMultiple(text string, items []string, options ...Option) ([]string, error) {
|
||||||
|
return listMultiple(text, items, applyOptions(options))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMultiple displays the list dialog, allowing multiple rows to be selected.
|
||||||
|
//
|
||||||
|
// Returns a nil slice on cancel, or ErrExtraButton.
|
||||||
|
func ListMultipleItems(text string, items ...string) ([]string, error) {
|
||||||
|
return ListMultiple(text, items)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultItems returns an Option to set the items to initally select.
|
||||||
|
func DefaultItems(items ...string) Option {
|
||||||
|
return funcOption(func(o *options) { o.defaultItems = items })
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisallowEmpty returns an Option to not allow zero rows to be selected (Windows and macOS only).
|
||||||
|
func DisallowEmpty() Option {
|
||||||
|
return funcOption(func(o *options) { o.disallowEmpty = true })
|
||||||
|
}
|
55
list_darwin.go
Normal file
55
list_darwin.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package zenity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ncruces/zenity/internal/zenutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func list(text string, items []string, opts options) (string, bool, error) {
|
||||||
|
var data zenutil.List
|
||||||
|
data.Items = items
|
||||||
|
data.Options.Prompt = &text
|
||||||
|
data.Options.Title = opts.title
|
||||||
|
data.Options.OK = opts.okLabel
|
||||||
|
data.Options.Cancel = opts.cancelLabel
|
||||||
|
data.Options.Default = opts.defaultItems
|
||||||
|
data.Options.Empty = !opts.disallowEmpty
|
||||||
|
|
||||||
|
out, err := zenutil.Run(opts.ctx, "list", data)
|
||||||
|
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||||
|
return "", false, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
return string(bytes.TrimSuffix(out, []byte{'\n'})), true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func listMultiple(text string, items []string, opts options) ([]string, error) {
|
||||||
|
var data zenutil.List
|
||||||
|
data.Items = items
|
||||||
|
data.Options.Prompt = &text
|
||||||
|
data.Options.Title = opts.title
|
||||||
|
data.Options.OK = opts.okLabel
|
||||||
|
data.Options.Cancel = opts.cancelLabel
|
||||||
|
data.Options.Default = opts.defaultItems
|
||||||
|
data.Options.Empty = !opts.disallowEmpty
|
||||||
|
data.Options.Multiple = true
|
||||||
|
data.Separator = zenutil.Separator
|
||||||
|
|
||||||
|
out, err := zenutil.Run(opts.ctx, "list", data)
|
||||||
|
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out = bytes.TrimSuffix(out, []byte{'\n'})
|
||||||
|
if len(out) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return strings.Split(string(out), zenutil.Separator), nil
|
||||||
|
}
|
66
list_test.go
Normal file
66
list_test.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package zenity_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ncruces/zenity"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleList() {
|
||||||
|
zenity.List(
|
||||||
|
"Select items from the list below:",
|
||||||
|
[]string{"apples", "oranges", "bananas", "strawberries"},
|
||||||
|
zenity.Title("Select items from the list"),
|
||||||
|
zenity.DisallowEmpty(),
|
||||||
|
)
|
||||||
|
// Output:
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleListItems() {
|
||||||
|
zenity.ListItems(
|
||||||
|
"Select items from the list below:",
|
||||||
|
"apples", "oranges", "bananas", "strawberries")
|
||||||
|
// Output:
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleListMultiple() {
|
||||||
|
zenity.ListMultiple(
|
||||||
|
"Select items from the list below:",
|
||||||
|
[]string{"apples", "oranges", "bananas", "strawberries"},
|
||||||
|
zenity.Title("Select items from the list"),
|
||||||
|
zenity.DefaultItems("apples", "bananas"),
|
||||||
|
)
|
||||||
|
// Output:
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleListMultipleItems() {
|
||||||
|
zenity.ListMultipleItems(
|
||||||
|
"Select items from the list below:",
|
||||||
|
"apples", "oranges", "bananas", "strawberries")
|
||||||
|
// Output:
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListTimeout(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second/10)
|
||||||
|
|
||||||
|
_, _, err := zenity.List("", nil, zenity.Context(ctx))
|
||||||
|
if !os.IsTimeout(err) {
|
||||||
|
t.Error("did not timeout:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListCancel(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
_, _, err := zenity.List("", nil, zenity.Context(ctx))
|
||||||
|
if !errors.Is(err, context.Canceled) {
|
||||||
|
t.Error("was not canceled:", err)
|
||||||
|
}
|
||||||
|
}
|
11
list_unix.go
Normal file
11
list_unix.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// +build !windows,!darwin
|
||||||
|
|
||||||
|
package zenity
|
||||||
|
|
||||||
|
func list(text string, items []string, opts options) (string, bool, error) {
|
||||||
|
return "", false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func listMultiple(text string, items []string, opts options) ([]string, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
9
list_windows.go
Normal file
9
list_windows.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package zenity
|
||||||
|
|
||||||
|
func list(text string, items []string, opts options) (string, bool, error) {
|
||||||
|
return "", false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func listMultiple(text string, items []string, opts options) ([]string, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -41,6 +41,10 @@ type options struct {
|
||||||
ellipsize bool
|
ellipsize bool
|
||||||
defaultCancel bool
|
defaultCancel bool
|
||||||
|
|
||||||
|
// List options
|
||||||
|
disallowEmpty bool
|
||||||
|
defaultItems []string
|
||||||
|
|
||||||
// File selection options
|
// File selection options
|
||||||
directory bool
|
directory bool
|
||||||
confirmOverwrite bool
|
confirmOverwrite bool
|
||||||
|
|
Loading…
Reference in a new issue