Issue #62.
This commit is contained in:
parent
46705a38f5
commit
2359e42bb9
11 changed files with 63 additions and 37 deletions
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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{}),
|
||||
}
|
||||
|
|
|
@ -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{}),
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 })
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ type options struct {
|
|||
// Progress indication options
|
||||
maxValue int
|
||||
noCancel bool
|
||||
autoClose bool
|
||||
timeRemaining bool
|
||||
|
||||
// Context for timeout
|
||||
|
|
Loading…
Reference in a new issue