From 374ba8a90a2691d35d2d78340b92b5ca194b549e Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Sun, 25 Apr 2021 18:34:56 +0100 Subject: [PATCH] WIP: progress (macOS). --- internal/zenutil/osa_generated.go | 13 +++---- internal/zenutil/osascripts/progress.js | 46 +++++++++++-------------- internal/zenutil/run_darwin.go | 19 +++++----- progress.go | 35 +++++++++++++++++-- progress_darwin.go | 21 +++++++++++ zenity.go | 5 +++ 6 files changed, 93 insertions(+), 46 deletions(-) create mode 100644 progress_darwin.go diff --git a/internal/zenutil/osa_generated.go b/internal/zenutil/osa_generated.go index 367e8bc..ea669c5 100644 --- a/internal/zenutil/osa_generated.go +++ b/internal/zenutil/osa_generated.go @@ -56,16 +56,13 @@ app.includeStandardAdditions=true app.activate() ObjC.import('stdlib') ObjC.import('readline') -function run(args){Progress.totalUnitCount=100 -Progress.completedUnitCount=0 -Progress.description=args[0]||"Progress" -Progress.additionalDescription=args[1]||"Running..." +try{Progress.totalUnitCount=$.getenv('total')}catch{} +try{Progress.description=$.getenv('description')}catch{} while(true){var s try{s=$.readline('')}catch(e){if(e.errorNumber===-128)$.exit(1) break} -if(s.indexOf('#')===0){Progress.additionalDescription=s.slice(1).trim() +if(s.indexOf('#')===0){Progress.additionalDescription=s.slice(1) continue} var i=parseInt(s) -if(Number.isSafeInteger(i)){Progress.completedUnitCount=i -continue}} -Progress.completedUnitCount=100}` +if(i>=0&&Progress.totalUnitCount>0){Progress.completedUnitCount=i +continue}}` diff --git a/internal/zenutil/osascripts/progress.js b/internal/zenutil/osascripts/progress.js index 08b8a8e..424213e 100644 --- a/internal/zenutil/osascripts/progress.js +++ b/internal/zenutil/osascripts/progress.js @@ -5,32 +5,26 @@ app.activate() ObjC.import('stdlib') ObjC.import('readline') -function run(args) { - Progress.totalUnitCount = 100 - Progress.completedUnitCount = 0 - Progress.description = args[0] || "Progress" - Progress.additionalDescription = args[1] || "Running..." +try { Progress.totalUnitCount = $.getenv('total') } catch { } +try { Progress.description = $.getenv('description') } catch { } - while (true) { - var s - try { - s = $.readline('') - } catch (e) { - if (e.errorNumber === -128) $.exit(1) - break - } - - if (s.indexOf('#') === 0) { - Progress.additionalDescription = s.slice(1).trim() - continue - } - - var i = parseInt(s) - if (Number.isSafeInteger(i)) { - Progress.completedUnitCount = i - continue - } +while (true) { + var s + try { + s = $.readline('') + } catch (e) { + if (e.errorNumber === -128) $.exit(1) + break } - Progress.completedUnitCount = 100 -} + if (s.indexOf('#') === 0) { + Progress.additionalDescription = s.slice(1) + continue + } + + var i = parseInt(s) + if (i >= 0 && Progress.totalUnitCount > 0) { + Progress.completedUnitCount = i + continue + } +} \ No newline at end of file diff --git a/internal/zenutil/run_darwin.go b/internal/zenutil/run_darwin.go index 0104c18..78decbf 100644 --- a/internal/zenutil/run_darwin.go +++ b/internal/zenutil/run_darwin.go @@ -51,7 +51,7 @@ func Run(ctx context.Context, script string, data interface{}) ([]byte, error) { return cmd.Output() } -func RunProgress(ctx context.Context) (m *progressMonitor, err error) { +func RunProgress(ctx context.Context, env []string) (m *progressDialog, err error) { t, err := ioutil.TempDir("", "") if err != nil { return nil, err @@ -93,6 +93,7 @@ func RunProgress(ctx context.Context) (m *progressMonitor, err error) { } cmd = exec.Command(executable) + cmd.Env = env pipe, err := cmd.StdinPipe() if err != nil { return nil, err @@ -104,7 +105,7 @@ func RunProgress(ctx context.Context) (m *progressMonitor, err error) { ctx = context.Background() } - m = &progressMonitor{ + m = &progressDialog{ done: make(chan struct{}), lines: make(chan string), } @@ -139,13 +140,13 @@ func RunProgress(ctx context.Context) (m *progressMonitor, err error) { return } -type progressMonitor struct { +type progressDialog struct { err error done chan struct{} lines chan string } -func (m *progressMonitor) send(line string) error { +func (m *progressDialog) send(line string) error { select { case m.lines <- line: return nil @@ -154,18 +155,18 @@ func (m *progressMonitor) send(line string) error { } } -func (m *progressMonitor) Close() error { +func (m *progressDialog) Close() error { close(m.lines) <-m.done return m.err } -func (m *progressMonitor) Message(msg string) error { - return m.send("#" + msg) +func (m *progressDialog) Text(text string) error { + return m.send("#" + text) } -func (m *progressMonitor) Progress(progress int) error { - return m.send(strconv.Itoa(progress)) +func (m *progressDialog) Value(value int) error { + return m.send(strconv.Itoa(value)) } // File is internal. diff --git a/progress.go b/progress.go index dbbffb0..45fa4e5 100644 --- a/progress.go +++ b/progress.go @@ -1,7 +1,36 @@ package zenity -type ProgressMonitor interface { - Message(string) error - Progress(int) error +// Progress displays the progress indication dialog. +// +// Valid options: Title, Width, Height, OKLabel, CancelLabel, ExtraButton, +// Icon, MaxValue, Pulsate, NoCancel, TimeRemaining. +func Progress(options ...Option) (ProgressDialog, error) { + return progress(applyOptions(options)) +} + +type ProgressDialog interface { + Text(string) error + Value(int) error Close() error } + +// MaxValue returns an Option to set the maximum value (macOS only). +// The default value is 100. +func MaxValue(value int) Option { + return funcOption(func(o *options) { o.maxValue = value }) +} + +// Pulsate returns an Option to pulsate the progress bar. +func Pulsate() Option { + return funcOption(func(o *options) { o.maxValue = -1 }) +} + +// NoCancel returns an Option to hide the Cancel button (Unix only). +func NoCancel() Option { + return funcOption(func(o *options) { o.noCancel = 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 }) +} diff --git a/progress_darwin.go b/progress_darwin.go new file mode 100644 index 0000000..044176e --- /dev/null +++ b/progress_darwin.go @@ -0,0 +1,21 @@ +package zenity + +import ( + "strconv" + + "github.com/ncruces/zenity/internal/zenutil" +) + +func progress(opts options) (ProgressDialog, error) { + var env []string + if opts.title != nil { + env = append(env, "description="+*opts.title) + } + if opts.maxValue == 0 { + opts.maxValue = 100 + } + if opts.maxValue >= 0 { + env = append(env, "total="+strconv.Itoa(opts.maxValue)) + } + return zenutil.RunProgress(opts.ctx, env) +} diff --git a/zenity.go b/zenity.go index 0b872e9..b125364 100644 --- a/zenity.go +++ b/zenity.go @@ -57,6 +57,11 @@ type options struct { color color.Color showPalette bool + // Progress indication options + maxValue int + noCancel bool + timeRemaining bool + // Context for timeout ctx context.Context }