Use AppleScript for color (macos).
This commit is contained in:
parent
9668c61d8b
commit
9460254709
10 changed files with 102 additions and 107 deletions
|
@ -35,8 +35,5 @@ Why reinvent this particular wheel?
|
||||||
* WSL/Cygwin/MSYS2 [support](https://github.com/ncruces/zenity/wiki/Zenity-for-WSL,-Cygwin,-MSYS2)
|
* WSL/Cygwin/MSYS2 [support](https://github.com/ncruces/zenity/wiki/Zenity-for-WSL,-Cygwin,-MSYS2)
|
||||||
* on macOS:
|
* on macOS:
|
||||||
* only dependency is `osascript`
|
* only dependency is `osascript`
|
||||||
(with [JXA](https://developer.apple.com/library/archive/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/Articles/Introduction.html);
|
|
||||||
`html/template` makes JavaScript easy to template)
|
|
||||||
* on other Unixes:
|
* on other Unixes:
|
||||||
* wraps either one of `qarma`, `zenity`, `matedialog`,\
|
* wraps either one of `zenity`, `qarma`, `matedialog`
|
||||||
in that order of preference
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ func SelectColor(options ...Option) (color.Color, error) {
|
||||||
var data zenutil.Color
|
var data zenutil.Color
|
||||||
if opts.color != nil {
|
if opts.color != nil {
|
||||||
r, g, b, _ := opts.color.RGBA()
|
r, g, b, _ := opts.color.RGBA()
|
||||||
data.Color = []float32{float32(r) / 0xffff, float32(g) / 0xffff, float32(b) / 0xffff}
|
data.Color = []uint32{r, g, b}
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := zenutil.Run("color", data)
|
out, err := zenutil.Run("color", data)
|
||||||
|
|
|
@ -3,78 +3,77 @@
|
||||||
|
|
||||||
package zenutil
|
package zenutil
|
||||||
|
|
||||||
import "html/template"
|
import "encoding/json"
|
||||||
|
import "text/template"
|
||||||
|
|
||||||
var scripts = template.Must(template.New("").Parse(`
|
var scripts = template.Must(template.New("").Funcs(template.FuncMap{"json": func(v interface{}) (string, error) {
|
||||||
{{define "color"}}<script>var app = Application.currentApplication()
|
b, err := json.Marshal(v)
|
||||||
app.includeStandardAdditions = true
|
return string(b), err
|
||||||
app.activate()
|
}}).Parse(`
|
||||||
var opts = {}
|
{{define "color" -}}tell application (path to frontmost application as text)
|
||||||
|
activate
|
||||||
{{if .Color -}}
|
{{if .Color -}}
|
||||||
opts.defaultColor = {{.Color}}
|
set c to choose color default color { {{index .Color 0}}, {{index .Color 1}}, {{index .Color 2}} }
|
||||||
{{end -}}
|
{{else -}}
|
||||||
var res = app.chooseColor(opts)
|
set c to choose color
|
||||||
if (Array.isArray(res)) {
|
{{end}}
|
||||||
res[0] = Math.round(255*res[0])
|
"rgb(" & (item 1 of c) div 257 & "," & (item 2 of c) div 257 & "," & (item 3 of c) div 257 & ")"
|
||||||
res[1] = Math.round(255*res[1])
|
end tell
|
||||||
res[2] = Math.round(255*res[2])
|
{{- end}}
|
||||||
'rgb('+res+')'
|
{{define "file" -}}var app = Application.currentApplication()
|
||||||
}
|
|
||||||
</script>{{end}}
|
|
||||||
{{define "file"}}<script>var app = Application.currentApplication()
|
|
||||||
app.includeStandardAdditions = true
|
app.includeStandardAdditions = true
|
||||||
app.activate()
|
app.activate()
|
||||||
var opts = {}
|
var opts = {}
|
||||||
{{if .Prompt -}}
|
{{if .Prompt -}}
|
||||||
opts.withPrompt = {{.Prompt}}
|
opts.withPrompt = {{json .Prompt}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Type -}}
|
{{if .Type -}}
|
||||||
opts.ofType = {{.Type}}
|
opts.ofType = {{json .Type}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Name -}}
|
{{if .Name -}}
|
||||||
opts.defaultName = {{.Name}}
|
opts.defaultName = {{json .Name}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Location -}}
|
{{if .Location -}}
|
||||||
opts.defaultLocation = {{.Location}}
|
opts.defaultLocation = {{json .Location}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Invisibles -}}
|
{{if .Invisibles -}}
|
||||||
opts.invisibles = {{.Invisibles}}
|
opts.invisibles = {{json .Invisibles}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Multiple -}}
|
{{if .Multiple -}}
|
||||||
opts.multipleSelectionsAllowed = {{.Multiple}}
|
opts.multipleSelectionsAllowed = {{json .Multiple}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
var res = app[{{.Operation}}](opts)
|
var res = app[{{json .Operation}}](opts)
|
||||||
if (Array.isArray(res)) {
|
if (Array.isArray(res)) {
|
||||||
res.join({{.Separator}})
|
res.join({{json .Separator}})
|
||||||
} else {
|
} else {
|
||||||
res.toString()
|
res.toString()
|
||||||
}
|
}
|
||||||
</script>{{end}}
|
{{- end}}
|
||||||
{{define "msg"}}<script>var app = Application.currentApplication()
|
{{define "msg" -}}var app = Application.currentApplication()
|
||||||
app.includeStandardAdditions = true
|
app.includeStandardAdditions = true
|
||||||
app.activate()
|
app.activate()
|
||||||
var opts = {}
|
var opts = {}
|
||||||
{{if .Message -}}
|
{{if .Message -}}
|
||||||
opts.message = {{.Message}}
|
opts.message = {{json .Message}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .As -}}
|
{{if .As -}}
|
||||||
opts.as = {{.As}}
|
opts.as = {{json .As}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Title -}}
|
{{if .Title -}}
|
||||||
opts.withTitle = {{.Title}}
|
opts.withTitle = {{json .Title}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Icon -}}
|
{{if .Icon -}}
|
||||||
opts.withIcon = {{.Icon}}
|
opts.withIcon = {{json .Icon}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Buttons -}}
|
{{if .Buttons -}}
|
||||||
opts.buttons = {{.Buttons}}
|
opts.buttons = {{json .Buttons}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Default -}}
|
{{if .Default -}}
|
||||||
opts.defaultButton = {{.Default}}
|
opts.defaultButton = {{json .Default}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Cancel -}}
|
{{if .Cancel -}}
|
||||||
opts.cancelButton = {{.Cancel}}
|
opts.cancelButton = {{json .Cancel}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
var res = app[{{.Operation}}]({{.Text}}, opts).buttonReturned
|
var res = app[{{json .Operation}}]({{json .Text}}, opts).buttonReturned
|
||||||
res === {{.Extra}} ? res : void 0
|
res === {{json .Extra}} ? res : void 0
|
||||||
</script>{{end}}`))
|
{{- end}}`))
|
||||||
|
|
|
@ -27,7 +27,7 @@ func main() {
|
||||||
|
|
||||||
str.WriteString("\n" + `{{define "`)
|
str.WriteString("\n" + `{{define "`)
|
||||||
str.WriteString(strings.TrimSuffix(name, filepath.Ext(name)))
|
str.WriteString(strings.TrimSuffix(name, filepath.Ext(name)))
|
||||||
str.WriteString(`"}}<script>`)
|
str.WriteString(`" -}}`)
|
||||||
|
|
||||||
func() {
|
func() {
|
||||||
in, err := os.Open(filepath.Join(dir, name))
|
in, err := os.Open(filepath.Join(dir, name))
|
||||||
|
@ -49,7 +49,7 @@ func main() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
str.WriteString("</script>{{end}}")
|
str.WriteString("{{- end}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := os.Create("osa_generated.go")
|
out, err := os.Create("osa_generated.go")
|
||||||
|
@ -73,7 +73,11 @@ var generator = template.Must(template.New("").Parse(`// Code generated by zenit
|
||||||
|
|
||||||
package zenutil
|
package zenutil
|
||||||
|
|
||||||
import "html/template"
|
import "encoding/json"
|
||||||
|
import "text/template"
|
||||||
|
|
||||||
var scripts = template.Must(template.New("").Parse(` + "`{{.}}`" + `))
|
var scripts = template.Must(template.New("").Funcs(template.FuncMap{"json": func(v interface{}) (string, error) {
|
||||||
|
b, err := json.Marshal(v)
|
||||||
|
return string(b), err
|
||||||
|
}}).Parse(` + "`{{.}}`" + `))
|
||||||
`))
|
`))
|
||||||
|
|
9
internal/zenutil/osascripts/color.applescript
Normal file
9
internal/zenutil/osascripts/color.applescript
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
tell application (path to frontmost application as text)
|
||||||
|
activate
|
||||||
|
{{if .Color -}}
|
||||||
|
set c to choose color default color { {{index .Color 0}}, {{index .Color 1}}, {{index .Color 2}} }
|
||||||
|
{{else -}}
|
||||||
|
set c to choose color
|
||||||
|
{{end}}
|
||||||
|
"rgb(" & (item 1 of c) div 257 & "," & (item 2 of c) div 257 & "," & (item 3 of c) div 257 & ")"
|
||||||
|
end tell
|
|
@ -1,17 +0,0 @@
|
||||||
var app = Application.currentApplication()
|
|
||||||
app.includeStandardAdditions = true
|
|
||||||
app.activate()
|
|
||||||
|
|
||||||
var opts = {}
|
|
||||||
|
|
||||||
{{if .Color -}}
|
|
||||||
opts.defaultColor = {{.Color}}
|
|
||||||
{{end -}}
|
|
||||||
|
|
||||||
var res = app.chooseColor(opts)
|
|
||||||
if (Array.isArray(res)) {
|
|
||||||
res[0] = Math.round(255*res[0])
|
|
||||||
res[1] = Math.round(255*res[1])
|
|
||||||
res[2] = Math.round(255*res[2])
|
|
||||||
'rgb('+res+')'
|
|
||||||
}
|
|
|
@ -5,27 +5,27 @@ app.activate()
|
||||||
var opts = {}
|
var opts = {}
|
||||||
|
|
||||||
{{if .Prompt -}}
|
{{if .Prompt -}}
|
||||||
opts.withPrompt = {{.Prompt}}
|
opts.withPrompt = {{json .Prompt}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Type -}}
|
{{if .Type -}}
|
||||||
opts.ofType = {{.Type}}
|
opts.ofType = {{json .Type}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Name -}}
|
{{if .Name -}}
|
||||||
opts.defaultName = {{.Name}}
|
opts.defaultName = {{json .Name}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Location -}}
|
{{if .Location -}}
|
||||||
opts.defaultLocation = {{.Location}}
|
opts.defaultLocation = {{json .Location}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Invisibles -}}
|
{{if .Invisibles -}}
|
||||||
opts.invisibles = {{.Invisibles}}
|
opts.invisibles = {{json .Invisibles}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{if .Multiple -}}
|
{{if .Multiple -}}
|
||||||
opts.multipleSelectionsAllowed = {{.Multiple}}
|
opts.multipleSelectionsAllowed = {{json .Multiple}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
|
||||||
var res = app[{{.Operation}}](opts)
|
var res = app[{{json .Operation}}](opts)
|
||||||
if (Array.isArray(res)) {
|
if (Array.isArray(res)) {
|
||||||
res.join({{.Separator}})
|
res.join({{json .Separator}})
|
||||||
} else {
|
} else {
|
||||||
res.toString()
|
res.toString()
|
||||||
}
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
var app = Application.currentApplication()
|
|
||||||
app.includeStandardAdditions = true
|
|
||||||
app.activate()
|
|
||||||
|
|
||||||
var opts = {}
|
|
||||||
|
|
||||||
{{if .Message -}}
|
|
||||||
opts.message = {{.Message}}
|
|
||||||
{{end -}}
|
|
||||||
{{if .As -}}
|
|
||||||
opts.as = {{.As}}
|
|
||||||
{{end -}}
|
|
||||||
{{if .Title -}}
|
|
||||||
opts.withTitle = {{.Title}}
|
|
||||||
{{end -}}
|
|
||||||
{{if .Icon -}}
|
|
||||||
opts.withIcon = {{.Icon}}
|
|
||||||
{{end -}}
|
|
||||||
{{if .Buttons -}}
|
|
||||||
opts.buttons = {{.Buttons}}
|
|
||||||
{{end -}}
|
|
||||||
{{if .Default -}}
|
|
||||||
opts.defaultButton = {{.Default}}
|
|
||||||
{{end -}}
|
|
||||||
{{if .Cancel -}}
|
|
||||||
opts.cancelButton = {{.Cancel}}
|
|
||||||
{{end -}}
|
|
||||||
|
|
||||||
var res = app[{{.Operation}}]({{.Text}}, opts).buttonReturned
|
|
||||||
res === {{.Extra}} ? res : void 0
|
|
30
internal/zenutil/osascripts/msg.js
Normal file
30
internal/zenutil/osascripts/msg.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
var app = Application.currentApplication()
|
||||||
|
app.includeStandardAdditions = true
|
||||||
|
app.activate()
|
||||||
|
|
||||||
|
var opts = {}
|
||||||
|
|
||||||
|
{{if .Message -}}
|
||||||
|
opts.message = {{json .Message}}
|
||||||
|
{{end -}}
|
||||||
|
{{if .As -}}
|
||||||
|
opts.as = {{json .As}}
|
||||||
|
{{end -}}
|
||||||
|
{{if .Title -}}
|
||||||
|
opts.withTitle = {{json .Title}}
|
||||||
|
{{end -}}
|
||||||
|
{{if .Icon -}}
|
||||||
|
opts.withIcon = {{json .Icon}}
|
||||||
|
{{end -}}
|
||||||
|
{{if .Buttons -}}
|
||||||
|
opts.buttons = {{json .Buttons}}
|
||||||
|
{{end -}}
|
||||||
|
{{if .Default -}}
|
||||||
|
opts.defaultButton = {{json .Default}}
|
||||||
|
{{end -}}
|
||||||
|
{{if .Cancel -}}
|
||||||
|
opts.cancelButton = {{json .Cancel}}
|
||||||
|
{{end -}}
|
||||||
|
|
||||||
|
var res = app[{{json .Operation}}]({{json .Text}}, opts).buttonReturned
|
||||||
|
res === {{json .Extra}} ? res : void 0
|
|
@ -15,19 +15,22 @@ func Run(script string, data interface{}) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := buf.String()
|
script = buf.String()
|
||||||
res = res[len("<script>") : len(res)-len("\n</script>")]
|
lang := "AppleScript"
|
||||||
|
if strings.HasPrefix(script, "var app") {
|
||||||
|
lang = "JavaScript"
|
||||||
|
}
|
||||||
|
|
||||||
if Command {
|
if Command {
|
||||||
path, err := exec.LookPath("osascript")
|
path, err := exec.LookPath("osascript")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
os.Stderr.Close()
|
os.Stderr.Close()
|
||||||
syscall.Exec(path, []string{"osascript", "-l", "JavaScript", "-e", res}, nil)
|
syscall.Exec(path, []string{"osascript", "-l", lang, "-e", script}, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command("osascript", "-l", "JavaScript")
|
cmd := exec.Command("osascript", "-l", lang)
|
||||||
cmd.Stdin = strings.NewReader(res)
|
cmd.Stdin = strings.NewReader(script)
|
||||||
return cmd.Output()
|
return cmd.Output()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +46,7 @@ type File struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Color struct {
|
type Color struct {
|
||||||
Color []float32
|
Color []uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type Msg struct {
|
type Msg struct {
|
||||||
|
|
Loading…
Reference in a new issue