From 2acdf8ef7f60a1e21a205db680b002a75a456ddf Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Sat, 18 Jan 2020 12:40:16 +0000 Subject: [PATCH] Color dialog (windows). --- color_test.go | 20 +++++++++++++ color_windows.go | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ zenity.go | 16 ++++++++++ 3 files changed, 112 insertions(+) create mode 100644 color_test.go create mode 100644 color_windows.go diff --git a/color_test.go b/color_test.go new file mode 100644 index 0000000..26baf03 --- /dev/null +++ b/color_test.go @@ -0,0 +1,20 @@ +package zenity_test + +import ( + "image/color" + + "github.com/ncruces/zenity" +) + +func ExampleSelectColor() { + zenity.SelectColor( + zenity.Color(color.RGBA{R: 0x66, G: 0x33, B: 0x99, A: 0xff})) + // Output: +} + +func ExampleSelectColor_palette() { + zenity.SelectColor( + zenity.ShowPalette(), + zenity.Color(color.RGBA{R: 0x66, G: 0x33, B: 0x99, A: 0xff})) + // Output: +} diff --git a/color_windows.go b/color_windows.go new file mode 100644 index 0000000..cefeec5 --- /dev/null +++ b/color_windows.go @@ -0,0 +1,76 @@ +package zenity + +import ( + "image/color" + "runtime" + "sync" + "unsafe" +) + +var ( + chooseColor = comdlg32.NewProc("ChooseColorW") + + savedColors = [16]uint32{} + colorsMutex sync.Mutex +) + +func init() { + for i := range savedColors { + savedColors[i] = 0xffffff + } +} + +func SelectColor(options ...Option) (color.Color, error) { + opts := optsParse(options) + + // load custom colors + colorsMutex.Lock() + customColors := savedColors + colorsMutex.Unlock() + + var args _CHOOSECOLORW + args.StructSize = uint32(unsafe.Sizeof(args)) + args.CustColors = &customColors + + if opts.color != nil { + args.Flags |= 0x1 // CC_RGBINIT + r, g, b, _ := opts.color.RGBA() + args.RgbResult = (r >> 8 << 0) | (g >> 8 << 8) | (b >> 8 << 16) + } + if opts.palette { + args.Flags |= 4 // CC_PREVENTFULLOPEN + } else { + args.Flags |= 2 // CC_FULLOPEN + } + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + n, _, _ := chooseColor.Call(uintptr(unsafe.Pointer(&args))) + + // save custom colors back + colorsMutex.Lock() + savedColors = customColors + colorsMutex.Unlock() + + if n == 0 { + return nil, commDlgError() + } + + r := uint8(args.RgbResult >> 0) + g := uint8(args.RgbResult >> 8) + b := uint8(args.RgbResult >> 16) + return color.RGBA{R: r, G: g, B: b, A: 255}, nil +} + +type _CHOOSECOLORW struct { + StructSize uint32 + Owner uintptr + Instance uintptr + RgbResult uint32 + CustColors *[16]uint32 + Flags uint32 + CustData uintptr + FnHook uintptr + TemplateName *uint16 +} diff --git a/zenity.go b/zenity.go index f319cd9..8db4ec8 100644 --- a/zenity.go +++ b/zenity.go @@ -1,5 +1,7 @@ package zenity +import "image/color" + // Errors type constError string @@ -24,6 +26,10 @@ type options struct { hidden bool filters []FileFilter + // Color selection options + color color.Color + palette bool + // Message options icon MessageIcon ok string @@ -104,6 +110,16 @@ func (f FileFilters) Build() Option { return func(o *options) { o.filters = append(o.filters, f...) } } +// Color selection options + +func Color(c color.Color) Option { + return func(o *options) { o.color = c } +} + +func ShowPalette() Option { + return func(o *options) { o.palette = true } +} + // Message options // MessageIcon is the enumeration for message dialog icons.