diff --git a/cmd/zenity/main.go b/cmd/zenity/main.go index e3a73ca..994dd99 100644 --- a/cmd/zenity/main.go +++ b/cmd/zenity/main.go @@ -70,10 +70,10 @@ var ( username bool // List options - columns int - checklist bool - radiolist bool - allowEmpty bool + columns int + checklist bool + radiolist bool + disallowEmpty bool // Calendar options year uint @@ -242,7 +242,7 @@ func parseFlags() []string { fset.Bool("hide-header", true, "Hide the column headers") fset.BoolVar(&checklist, "checklist", false, "Use check boxes for the first column (Unix only)") fset.BoolVar(&radiolist, "radiolist", false, "Use radio buttons for the first column (Unix only)") - fset.BoolVar(&allowEmpty, "allow-empty", true, "Allow empty selection (macOS only)") + fset.BoolVar(&disallowEmpty, "disallow-empty", false, "Disallow empty selection (Windows and macOS only)") // Calendar options fset.UintVar(&year, "year", 0, "Set the calendar `year`") @@ -538,7 +538,7 @@ func loadFlags() []zenity.Option { if radiolist { opts = append(opts, zenity.RadioList()) } - if !allowEmpty { + if disallowEmpty { opts = append(opts, zenity.DisallowEmpty()) } diff --git a/internal/win/user32.go b/internal/win/user32.go index eb9fb68..59b52d6 100644 --- a/internal/win/user32.go +++ b/internal/win/user32.go @@ -142,6 +142,7 @@ const ( ES_AUTOHSCROLL = 0x0080 // List box control styles + LBS_NOTIFY = 0x0001 LBS_EXTENDEDSEL = 0x0800 // Month calendar control styles diff --git a/list.go b/list.go index 732d1e5..f8ff565 100644 --- a/list.go +++ b/list.go @@ -57,7 +57,7 @@ func DefaultItems(items ...string) Option { return funcOption(func(o *options) { o.defaultItems = items }) } -// DisallowEmpty returns an Option to not allow zero items to be selected (macOS only). +// DisallowEmpty returns an Option to not allow zero items to be selected (Windows and macOS only). func DisallowEmpty() Option { return funcOption(func(o *options) { o.disallowEmpty = true }) } diff --git a/list_windows.go b/list_windows.go index 3e2f24b..3b97f13 100644 --- a/list_windows.go +++ b/list_windows.go @@ -31,17 +31,19 @@ func listDlg(text string, items []string, multiple bool, opts options) ([]string } dlg := &listDialog{ - items: items, - multiple: multiple, + items: items, + multiple: multiple, + disallowEmpty: opts.disallowEmpty, } return dlg.setup(text, opts) } type listDialog struct { - items []string - multiple bool - out []string - err error + items []string + multiple bool + disallowEmpty bool + out []string + err error wnd win.HWND textCtl win.HWND @@ -84,7 +86,7 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) { strptr("STATIC"), strptr(text), _WS_ZEN_LABEL, 12, 10, 241, 16, dlg.wnd, 0, instance, nil) - var flags uint32 = _WS_ZEN_CONTROL | win.WS_VSCROLL + var flags uint32 = _WS_ZEN_CONTROL | win.WS_VSCROLL | win.LBS_NOTIFY if dlg.multiple { flags |= win.LBS_EXTENDEDSEL } @@ -120,6 +122,7 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) { } } + dlg.update() dlg.layout(getDPI(dlg.wnd)) centerWindow(dlg.wnd) win.SetFocus(dlg.listCtl) @@ -166,6 +169,20 @@ func (dlg *listDialog) layout(dpi dpi) { } } +func (dlg *listDialog) update() { + if dlg.disallowEmpty { + var enable bool + if dlg.multiple { + len := win.SendMessage(dlg.listCtl, win.LB_GETSELCOUNT, 0, 0) + enable = int32(len) > 0 + } else { + idx := win.SendMessage(dlg.listCtl, win.LB_GETCURSEL, 0, 0) + enable = int32(idx) >= 0 + } + win.EnableWindow(dlg.okBtn, enable) + } +} + func listProc(wnd win.HWND, msg uint32, wparam uintptr, lparam *unsafe.Pointer) uintptr { var dlg *listDialog switch msg { @@ -189,6 +206,7 @@ func listProc(wnd win.HWND, msg uint32, wparam uintptr, lparam *unsafe.Pointer) case win.WM_COMMAND: switch wparam { default: + dlg.update() return 1 case win.IDOK, win.IDYES: if dlg.multiple {