This commit is contained in:
Nuno Cruces 2023-08-03 12:55:59 +01:00
parent 46705a38f5
commit 2359e42bb9
11 changed files with 63 additions and 37 deletions

View file

@ -609,6 +609,9 @@ func loadFlags() []zenity.Option {
if noCancel {
opts = append(opts, zenity.NoCancel())
}
if autoClose {
opts = append(opts, zenity.AutoClose())
}
if timeRemaining {
opts = append(opts, zenity.TimeRemaining())
}

View file

@ -14,6 +14,9 @@ import (
)
func progress(opts ...zenity.Option) (err error) {
const scale = 16777216
opts = append(opts, zenity.MaxValue(scale*100))
dlg, err := zenity.Progress(opts...)
if err != nil {
return err
@ -30,7 +33,7 @@ func progress(opts ...zenity.Option) (err error) {
if err := dlg.Text(text); err != nil {
return err
}
if err := dlg.Value(int(math.Round(percentage))); err != nil {
if err := dlg.Value(int(math.Round(scale * percentage))); err != nil {
return err
}
@ -54,12 +57,9 @@ func progress(opts ...zenity.Option) (err error) {
return err
}
} else if v, err := strconv.ParseFloat(line, 64); err == nil {
if err := dlg.Value(int(math.Round(v))); err != nil {
if err := dlg.Value(int(math.Round(scale * v))); err != nil {
return err
}
if v >= 100 && autoClose {
return dlg.Close()
}
}
continue
case <-dlg.Done():

View file

@ -20,6 +20,7 @@ type progressDialog struct {
ctx context.Context
cmd *exec.Cmd
max int
close bool
percent bool
closed int32
lines chan string
@ -41,6 +42,9 @@ func (d *progressDialog) Text(text string) error {
}
func (d *progressDialog) Value(value int) error {
if value >= d.max && d.close {
return d.Close()
}
if d.percent {
return d.send(strconv.FormatFloat(100*float64(value)/float64(d.max), 'f', -1, 64))
} else {

View file

@ -46,7 +46,7 @@ func Run(ctx context.Context, script string, data any) ([]byte, error) {
}
// RunProgress is internal.
func RunProgress(ctx context.Context, max int, data Progress) (dlg *progressDialog, err error) {
func RunProgress(ctx context.Context, max int, close bool, data Progress) (_ *progressDialog, err error) {
var buf bytes.Buffer
err = scripts.ExecuteTemplate(&buf, "progress", data)
if err != nil {
@ -108,10 +108,11 @@ func RunProgress(ctx context.Context, max int, data Progress) (dlg *progressDial
return nil, err
}
dlg = &progressDialog{
dlg := &progressDialog{
ctx: ctx,
cmd: cmd,
max: max,
close: close,
lines: make(chan string),
done: make(chan struct{}),
}

View file

@ -54,7 +54,7 @@ func Run(ctx context.Context, args []string) ([]byte, error) {
}
// RunProgress is internal.
func RunProgress(ctx context.Context, max int, extra *string, args []string) (*progressDialog, error) {
func RunProgress(ctx context.Context, max int, close bool, extra *string, args []string) (*progressDialog, error) {
pathOnce.Do(initPath)
if Command && path != "" {
if Timeout > 0 {
@ -85,6 +85,7 @@ func RunProgress(ctx context.Context, max int, extra *string, args []string) (*p
cmd: cmd,
max: max,
percent: true,
close: close,
lines: make(chan string),
done: make(chan struct{}),
}

View file

@ -31,7 +31,7 @@ func TestRun_context(t *testing.T) {
}
func TestRunProgress(t *testing.T) {
_, err := RunProgress(nil, 100, nil, []string{"--version"})
_, err := RunProgress(nil, 100, false, nil, []string{"--version"})
if skip, err := skip(err); skip {
t.Skip("skipping:", err)
}

View file

@ -47,6 +47,11 @@ func NoCancel() Option {
return funcOption(func(o *options) { o.noCancel = true })
}
// AutoClose returns an Option to dismiss the dialog when 100% has been reached.
func AutoClose() Option {
return funcOption(func(o *options) { o.autoClose = true })
}
// TimeRemaining returns an Option to estimate when progress will reach 100% (Unix only).
func TimeRemaining() Option {
return funcOption(func(o *options) { o.timeRemaining = true })

View file

@ -23,5 +23,5 @@ func progress(opts options) (ProgressDialog, error) {
data.WindowIcon = i
}
return zenutil.RunProgress(opts.ctx, opts.maxValue, data)
return zenutil.RunProgress(opts.ctx, opts.maxValue, opts.autoClose, data)
}

View file

@ -19,8 +19,11 @@ func progress(opts options) (ProgressDialog, error) {
if opts.noCancel {
args = append(args, "--no-cancel")
}
if opts.autoClose {
args = append(args, "--auto-close")
}
if opts.timeRemaining {
args = append(args, "--time-remaining")
}
return zenutil.RunProgress(opts.ctx, opts.maxValue, opts.extraButton, args)
return zenutil.RunProgress(opts.ctx, opts.maxValue, opts.autoClose, opts.extraButton, args)
}

View file

@ -29,8 +29,9 @@ func progress(opts options) (ProgressDialog, error) {
}
dlg := &progressDialog{
done: make(chan struct{}),
max: opts.maxValue,
done: make(chan struct{}),
max: opts.maxValue,
close: opts.autoClose,
}
dlg.init.Add(1)
@ -44,10 +45,11 @@ func progress(opts options) (ProgressDialog, error) {
}
type progressDialog struct {
init sync.WaitGroup
done chan struct{}
max int
err error
init sync.WaitGroup
done chan struct{}
err error
max int
close bool
wnd win.HWND
textCtl win.HWND
@ -69,6 +71,9 @@ func (d *progressDialog) Text(text string) error {
}
func (d *progressDialog) Value(value int) error {
if value >= d.max && d.close {
return d.Close()
}
select {
default:
win.SendMessage(d.progCtl, win.PBM_SETPOS, uintptr(value), 0)
@ -156,10 +161,12 @@ func (dlg *progressDialog) setup(opts options) error {
nil, flags,
12, 30, 241, 16, dlg.wnd, 0, instance, nil)
dlg.okBtn, _ = win.CreateWindowEx(0,
strptr("BUTTON"), strptr(quoteAccelerators(*opts.okLabel)),
_WS_ZEN_BUTTON|win.BS_DEFPUSHBUTTON|win.WS_DISABLED,
12, 58, 75, 24, dlg.wnd, win.IDOK, instance, nil)
if !opts.noCancel || !opts.autoClose {
dlg.okBtn, _ = win.CreateWindowEx(0,
strptr("BUTTON"), strptr(quoteAccelerators(*opts.okLabel)),
_WS_ZEN_BUTTON|win.BS_DEFPUSHBUTTON|win.WS_DISABLED,
12, 58, 75, 24, dlg.wnd, win.IDOK, instance, nil)
}
if !opts.noCancel {
dlg.cancelBtn, _ = win.CreateWindowEx(0,
strptr("BUTTON"), strptr(quoteAccelerators(*opts.cancelLabel)),
@ -213,22 +220,23 @@ func (d *progressDialog) layout(dpi dpi) {
win.SetWindowPos(d.wnd, 0, 0, 0, dpi.scale(281), dpi.scale(133), win.SWP_NOMOVE|win.SWP_NOZORDER)
win.SetWindowPos(d.textCtl, 0, dpi.scale(12), dpi.scale(10), dpi.scale(241), dpi.scale(16), win.SWP_NOZORDER)
win.SetWindowPos(d.progCtl, 0, dpi.scale(12), dpi.scale(30), dpi.scale(241), dpi.scale(16), win.SWP_NOZORDER)
if d.extraBtn == 0 {
if d.cancelBtn == 0 {
win.SetWindowPos(d.okBtn, 0, dpi.scale(178), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
} else {
win.SetWindowPos(d.okBtn, 0, dpi.scale(95), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
win.SetWindowPos(d.cancelBtn, 0, dpi.scale(178), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
}
} else {
if d.cancelBtn == 0 {
win.SetWindowPos(d.okBtn, 0, dpi.scale(95), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
win.SetWindowPos(d.extraBtn, 0, dpi.scale(178), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
} else {
win.SetWindowPos(d.okBtn, 0, dpi.scale(12), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
win.SetWindowPos(d.extraBtn, 0, dpi.scale(95), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
win.SetWindowPos(d.cancelBtn, 0, dpi.scale(178), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
}
pos := 178
if d.cancelBtn != 0 {
win.SetWindowPos(d.cancelBtn, 0, dpi.scale(pos), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
pos -= 83
}
if d.extraBtn != 0 {
win.SetWindowPos(d.extraBtn, 0, dpi.scale(pos), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
pos -= 83
}
if d.okBtn != 0 {
win.SetWindowPos(d.okBtn, 0, dpi.scale(pos), dpi.scale(58), dpi.scale(75), dpi.scale(24), win.SWP_NOZORDER)
pos -= 83
}
if pos == 178 {
win.SetWindowPos(d.wnd, 0, 0, 0, dpi.scale(281), dpi.scale(97), win.SWP_NOMOVE|win.SWP_NOZORDER)
}
}

View file

@ -86,6 +86,7 @@ type options struct {
// Progress indication options
maxValue int
noCancel bool
autoClose bool
timeRemaining bool
// Context for timeout