Command-Line Tutorial (Part II): Making Progress and Finding Options

Author: Geoff Hutchison
Website: http://geoffhutchison.net/

Last time, we looked at Platypus, a program which creates native Mac applications, complete with double-clicking and drag-and-drop of files, around command-line scripts and programs. Scientists often have traditional UNIX tools, and this is one way to handle background tasks which require little user interaction.

What if you need a bit more interaction?

Progress

Platypus includes two simple options for showing progress in your application. The first is a simple "indeterminate progress bar" dialog which will at least show the user that something is happening. This can be accessed by checking the "Progress Bar" option in the main Platypus window.

Platypus Options for Output

Also available is the "text window" option, which wraps standard output and standard error into a window, which can be selected and copied by the user. Note that if you pick this option, you probably also wish to set the "Remain running after completion" advanced option. This leaves the text window open until the user decides to quit the program.

Platypus Text Output Window

Are We Done Yet?

Maybe these aren't enough for you. Maybe you want to show users how close the process is to being finished -- say to indicate that the Leopard release is 71% complete.

Progress Window

Unfortunately, Platypus isn't designed for this, but other programs are. This week, we'll expand to using Cocoa Dialog (http://cocoadialog.sourceforge.net/) to put up various forms of user interaction, including a percent complete box. You can even combine Platypus with CocoaDialog, as illustrated here (http://www.sveinbjorn.org/platypus_cocoadialog).

CocoaDialog is a native Mac OS X application, but it's really intended to be used from the command-line or a script. As indicated in the documentation (http://cocoadialog.sourceforge.net/documentation.html), it offers a range of user dialog boxes which give feedback to users or grab input from them. It's distributed under the terms of the GNU GPL, and since most people will call it directly (rather than linking to its code), you should be able to distribute it freely, no matter what license you use for your programs.

For these examples, we'll assume that you've just installed CocoaDialog in the main Applications folder.

User Options

There are a number of different dialog types, but let's start with a simple drop-down menu for options.

Drop Down Menu

This can be accessed by the following shell script command:

/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog standard-dropdown \
--text "Pick a flavor" --title "Flavor Options" --items "Apple" "Grape" "Cherry" \
--string-output

The result I got back was:

Cancel
Apple

So we'll need to do some processing -- the first line is whether the user clicked "OK" or "Cancel" and the second is the option picked. Yes, even if the user picked "Cancel," CocoaDialog will return the value in the menu. Perl is usually good at processing text, so I'll use that for my examples.

#!/usr/bin/perl -w
use strict;

our $CD = "/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog";

my $rv = `$CD standard-dropdown --text "Pick a flavor" \\
--title "Flavor Options" --items "Apple" "Grape" "Cherry" \\
--string-output`;
my ($button, $item) = split /\n/, $rv;

if ($button eq "Ok") {
  print "Item: $item\n";
} else {
  print "User canceled\n";
}

One last example, this time for text input.

Text Input Dialog

Here's our script:

#!/usr/bin/perl -w
use strict;

our $CD = "/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog";

my $rv = `$CD standard-inputbox --title "Command Options" --no-newline \\
    --informative-text "Add some command-options:" \\
    --text "Specify keywords here"`;

my ($button_rv, $keys) = split /\n/, $rv, 2;
if ($button_rv == 1) {
    print "Running with options: $keys\n";
} elsif ($button_rv == 2) {
    print "Cancelled\n";
}

And Finished!

So you can see, it's fairly easy to add user input to command-line programs and give feedback. This goes a long way toward making a UNIX tool feel more like a Mac application. We can now make a native Mac application for the Finder, drag-and-drop files, show dialog boxes for input, and put up progress bars. Not bad considering we haven't touched anything in Xcode.

I'll leave you with an example of that progress bar above. This is a Perl script -- the core is the "for(my $percent ..." loop, which prints a percentage to the $fh file (really a UNIX pipe to the CocoaDialog program) and counts to 900,000. Typically you might want to do something more useful, like run your Fortran program here.

If you have questions on the script, please post a comment to this tutorial and I'll be glad to go through step-by-step.

#!/usr/bin/perl -w

use strict;
use IO::File;

# Change the path if CocoaDialog is installed elsewhere
our $COCOA_DIALOG = "/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog";
die "$COCOA_DIALOG doesn't exist" unless -e $COCOA_DIALOG;

### Open a pipe to the program
# $fh is now our file handle to output 
my $fh = IO::File->new("|$COCOA_DIALOG progressbar --title ''");
die "no fh" unless defined $fh;
$fh->autoflush(1);

my $percent = 0;
for (my $percent = 0; $percent <= 100; $percent++) {
  ### Update the progressbar every percent
  print $fh "$percent Processing...\n";
  ### simulate a long operation (do whatever you want here
  1 for (0 .. 900_000);
}

### Close the filehandle to send an EOF and hide the box
$fh->close();

Next time, I'll focus on Pashua (http://www.bluem.net/downloads/pashua_en/), another tool which can be used to present real Mac windows for user input.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Feedback?

How are these tutorials going? Too long? Too short?

Are there particular topics you'd like me to cover? This general area seemed to be hotly requested and one which I understand well. (In addition to general command-line kung-fu.)

How am I doing?

So far, so good!

You are doing good! It is nice to have an overview of all the options in this area, and this is what you are doing. One tutorial per program is a good pace. In the end, it would also be good to have a list of goods and bads for all these options, and maybe a feature comparison list.

Thanks!

charles

going great

Everything is going great. Thanks for the tutorial series.

Platypus editing

This was a great tutorial. It was exactly what I was looking for in building a little application.

Here is a comment for making Platypus a little nicer. I am using the text ouput feature of Platypus. You can navigate within the application bundle that you create to find the MainMenu.nib file. From here you can change a number of things.... Give your app a brushed metal appearance.... Change the size of the text box.... Remove the scroll bar.... I am sure there are many of other fun things we can do with the nib.

Cheers

Don't worry, editing .nib files coming soon...

Well, I haven't gotten to .nib files yet. :-)

Yes, there are plenty of customization options with Platypus, Pashua, ... all of the above. I'm trying to go from simpler cases to more complicated ones. I do plan to talk about Interface Builder and .nib files, because it's an important part of making a command-line tool fit with a native Mac interface.