Color dialog (linux).

This commit is contained in:
Nuno Cruces 2020-01-21 16:13:45 +00:00
parent 9460254709
commit 0728bdf5ad
11 changed files with 114 additions and 17 deletions

View file

@ -11,6 +11,7 @@ Lots of things are missing.
For now, these are the only implemented dialogs: For now, these are the only implemented dialogs:
* [message](https://github.com/ncruces/zenity/wiki/Message-dialog) (error, info, question, warning) * [message](https://github.com/ncruces/zenity/wiki/Message-dialog) (error, info, question, warning)
* [file selection](https://github.com/ncruces/zenity/wiki/File-Selection-dialog) * [file selection](https://github.com/ncruces/zenity/wiki/File-Selection-dialog)
* [color selection](https://github.com/ncruces/zenity/wiki/Color-Selection-dialog)
Behavior on Windows, macOS and other Unixes might differ slightly. Behavior on Windows, macOS and other Unixes might differ slightly.
Some of that is intended (reflecting platform differences), Some of that is intended (reflecting platform differences),

View file

@ -2,6 +2,7 @@ package main
import ( import (
"flag" "flag"
"image/color"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -21,6 +22,7 @@ var (
warningDlg bool warningDlg bool
questionDlg bool questionDlg bool
fileSelectionDlg bool fileSelectionDlg bool
colorSelectionDlg bool
// General options // General options
title string title string
@ -46,6 +48,10 @@ var (
separator string separator string
fileFilters FileFilters fileFilters FileFilters
// Color selection options
initColor string
palette bool
// Windows specific options // Windows specific options
cygpath bool cygpath bool
wslpath bool wslpath bool
@ -77,6 +83,9 @@ func main() {
case multiple: case multiple:
lstResult(egestPaths(zenity.SelectFileMutiple(opts...))) lstResult(egestPaths(zenity.SelectFileMutiple(opts...)))
} }
case colorSelectionDlg:
clrResult(zenity.SelectColor(opts...))
} }
flag.Usage() flag.Usage()
@ -91,6 +100,7 @@ func setupFlags() {
flag.BoolVar(&warningDlg, "warning", false, "Display warning dialog") flag.BoolVar(&warningDlg, "warning", false, "Display warning dialog")
flag.BoolVar(&questionDlg, "question", false, "Display question dialog") flag.BoolVar(&questionDlg, "question", false, "Display question dialog")
flag.BoolVar(&fileSelectionDlg, "file-selection", false, "Display file selection dialog") flag.BoolVar(&fileSelectionDlg, "file-selection", false, "Display file selection dialog")
flag.BoolVar(&colorSelectionDlg, "color-selection", false, "Display color selection dialog")
// General options // General options
@ -119,6 +129,10 @@ func setupFlags() {
flag.StringVar(&separator, "separator", "|", "Set output separator character") flag.StringVar(&separator, "separator", "|", "Set output separator character")
flag.Var(&fileFilters, "file-filter", "Set a filename filter (NAME | PATTERN1 PATTERN2 ...)") flag.Var(&fileFilters, "file-filter", "Set a filename filter (NAME | PATTERN1 PATTERN2 ...)")
// Color selection options
flag.StringVar(&initColor, "color", "", "Set the color")
flag.BoolVar(&palette, "show-palette", false, "Show the palette")
// Windows specific options // Windows specific options
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
flag.BoolVar(&cygpath, "cygpath", false, "Use cygpath for path translation (Windows only)") flag.BoolVar(&cygpath, "cygpath", false, "Use cygpath for path translation (Windows only)")
@ -143,6 +157,9 @@ func validateFlags() {
if fileSelectionDlg { if fileSelectionDlg {
n++ n++
} }
if colorSelectionDlg {
n++
}
if n != 1 { if n != 1 {
flag.Usage() flag.Usage()
os.Exit(-1) os.Exit(-1)
@ -187,7 +204,9 @@ func loadFlags() []zenity.Option {
// File selection options // File selection options
options = append(options, fileFilters.Build()) options = append(options, fileFilters.Build())
if filename != "" {
options = append(options, zenity.Filename(ingestPath(filename))) options = append(options, zenity.Filename(ingestPath(filename)))
}
if directory { if directory {
options = append(options, zenity.Directory()) options = append(options, zenity.Directory())
} }
@ -203,6 +222,15 @@ func loadFlags() []zenity.Option {
zenutil.Separator = separator zenutil.Separator = separator
// Color selection options
if initColor != "" {
options = append(options, zenity.Color(zenutil.ParseColor(initColor)))
}
if palette {
options = append(options, zenity.ShowPalette())
}
return options return options
} }
@ -251,6 +279,20 @@ func lstResult(l []string, err error) {
os.Exit(0) os.Exit(0)
} }
func clrResult(c color.Color, err error) {
if err != nil {
os.Stderr.WriteString(err.Error())
os.Stderr.WriteString(zenutil.LineBreak)
os.Exit(-1)
}
if c == nil {
os.Exit(1)
}
os.Stdout.WriteString(zenutil.UnparseColor(c))
os.Stdout.WriteString(zenutil.LineBreak)
os.Exit(0)
}
func ingestPath(path string) string { func ingestPath(path string) string {
if runtime.GOOS == "windows" && path != "" { if runtime.GOOS == "windows" && path != "" {
var args []string var args []string

View file

@ -12,8 +12,8 @@ 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() n := color.NRGBA64Model.Convert(opts.color).(color.NRGBA64)
data.Color = []uint32{r, g, b} data.Color = []uint16{n.R, n.G, n.B}
} }
out, err := zenutil.Run("color", data) out, err := zenutil.Run("color", data)

View file

@ -8,13 +8,13 @@ import (
func ExampleSelectColor() { func ExampleSelectColor() {
zenity.SelectColor( zenity.SelectColor(
zenity.Color(color.RGBA{R: 0x66, G: 0x33, B: 0x99, A: 0xff})) zenity.Color(color.NRGBA{R: 0x66, G: 0x33, B: 0x99, A: 0x80}))
// Output: // Output:
} }
func ExampleSelectColor_palette() { func ExampleSelectColor_palette() {
zenity.SelectColor( zenity.SelectColor(
zenity.ShowPalette(), zenity.ShowPalette(),
zenity.Color(color.RGBA{R: 0x66, G: 0x33, B: 0x99, A: 0xff})) zenity.Color(color.NRGBA{R: 0x66, G: 0x33, B: 0x99, A: 0xff}))
// Output: // Output:
} }

40
color_unix.go Normal file
View file

@ -0,0 +1,40 @@
// +build !windows,!darwin
package zenity
import (
"image/color"
"os/exec"
"github.com/ncruces/zenity/internal/zenutil"
)
// Display color selection dialog.
//
// Returns nil on cancel.
//
// Valid options: Title, Color, ShowPalette.
func SelectColor(options ...Option) (color.Color, error) {
opts := optsParse(options)
args := []string{"--color-selection"}
if opts.title != "" {
args = append(args, "--title", opts.title)
}
if opts.color != nil {
args = append(args, "--color", zenutil.UnparseColor(opts.color))
}
if opts.palette {
args = append(args, "--show-palette")
}
out, err := zenutil.Run(args)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() != 255 {
return nil, nil
}
if err != nil {
return nil, err
}
return zenutil.ParseColor(string(out)), nil
}

View file

@ -34,8 +34,8 @@ func SelectColor(options ...Option) (color.Color, error) {
if opts.color != nil { if opts.color != nil {
args.Flags |= 0x1 // CC_RGBINIT args.Flags |= 0x1 // CC_RGBINIT
r, g, b, _ := opts.color.RGBA() n := color.NRGBAModel.Convert(opts.color).(color.NRGBA)
args.RgbResult = (r >> 8 << 0) | (g >> 8 << 8) | (b >> 8 << 16) args.RgbResult = uint32(n.R) | (uint32(n.G) << 8) | (uint32(n.B) << 16)
} }
if opts.palette { if opts.palette {
args.Flags |= 4 // CC_PREVENTFULLOPEN args.Flags |= 4 // CC_PREVENTFULLOPEN

View file

@ -39,6 +39,18 @@ func ParseColor(s string) color.Color {
} }
} }
c, _ := colornames.Map[strings.ToLower(s)] c, ok := colornames.Map[strings.ToLower(s)]
if ok {
return c return c
} }
return nil
}
func UnparseColor(c color.Color) string {
n := color.NRGBAModel.Convert(c).(color.NRGBA)
if n.A == 255 {
return fmt.Sprintf("rgb(%d,%d,%d)", n.R, n.G, n.B)
} else {
return fmt.Sprintf("rgba(%d,%d,%d,%f)", n.R, n.G, n.B, float32(n.A)/255)
}
}

View file

@ -17,7 +17,7 @@ set c to choose color default color { {{index .Color 0}}, {{index .Color 1}}, {{
{{else -}} {{else -}}
set c to choose color set c to choose color
{{end}} {{end}}
"rgb(" & (item 1 of c) div 257 & "," & (item 2 of c) div 257 & "," & (item 3 of c) div 257 & ")" "rgb(" & (item 1 of c) div 256 & "," & (item 2 of c) div 256 & "," & (item 3 of c) div 256 & ")"
end tell end tell
{{- end}} {{- end}}
{{define "file" -}}var app = Application.currentApplication() {{define "file" -}}var app = Application.currentApplication()

View file

@ -5,5 +5,5 @@ tell application (path to frontmost application as text)
{{else -}} {{else -}}
set c to choose color set c to choose color
{{end}} {{end}}
"rgb(" & (item 1 of c) div 257 & "," & (item 2 of c) div 257 & "," & (item 3 of c) div 257 & ")" "rgb(" & (item 1 of c) div 256 & "," & (item 2 of c) div 256 & "," & (item 3 of c) div 256 & ")"
end tell end tell

View file

@ -46,7 +46,7 @@ type File struct {
} }
type Color struct { type Color struct {
Color []uint32 Color []uint16
} }
type Msg struct { type Msg struct {

View file

@ -112,10 +112,12 @@ func (f FileFilters) Build() Option {
// Color selection options // Color selection options
// Option to set the color.
func Color(c color.Color) Option { func Color(c color.Color) Option {
return func(o *options) { o.color = c } return func(o *options) { o.color = c }
} }
// Option to show the palette.
func ShowPalette() Option { func ShowPalette() Option {
return func(o *options) { o.palette = true } return func(o *options) { o.palette = true }
} }