CocoaDialog
overview | download | documentation | examples | todo | sf.net project page

Easy way to invoke CocoaDialog

download

This is a simple wrapper script. Put it somewhere in your $PATH. For example, mine is ~/bin/CocoaDialog, and I have export PATH=$PATH:~/bin in my ~/.bash_profile.

Now from the shell or other scripts, I can just do CocoaDialog to invoke the program.

#!/usr/bin/perl
use strict;
use warnings;

my $path = "/Users/markstra/Applications"; # Change this!
my $cd = "$path/CocoaDialog.app/Contents/MacOS/CocoaDialog";

system($cd, @ARGV);
			

back to the top

bubble shell script

download

#!/bin/bash

CD_APP="$HOME/Applications/CocoaDialog.app"
CD="$CD_APP/Contents/MacOS/CocoaDialog"

### Simple example, one bubble
$CD bubble --debug --title "My first bubble" --text "How do you like it?"

### Changing the colors and icon
$CD bubble --debug --title "Setting colors" --text "Green to light green" \
	--background-top "00cb24" --background-bottom "aefe95" \
	--icon "hazard"

### Let's get a little more fancy.  Here are 2 bubbles, with custom icons,
### custom border colors, custom backgrounds, AND custom text colors.
### We'll even mix stock icons and custom icons.
$CD bubble --debug --titles "Bubble 1" "Second bubble"        \
	--texts "Body of bubble 1" "and body of bubble 2" \
	--border-colors "2100b4" "a25f0a"                 \
	--text-colors "180082" "000000"                   \
	--background-tops "aabdcf" "dfa723"               \
	--background-bottoms "86c7fe" "fdde88"            \
	--icon-files "/Users/markstra/Desktop/icon1.png"  \
	             "$CD_APP/Contents/Resources/globe.icns"

			

back to the top

ok-msgbox shell script

download

#!/bin/bash

CD="$HOME/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog"

rv=`$CD ok-msgbox --text "We need to make sure you see this message" \
    --informative-text "(Yes, the message was to inform you about itself)" \
		--no-newline --float`
if [ "$rv" == "1" ]; then
    echo "User said OK"
elif [ "$rv" == "2" ]; then
    echo "Canceling"
    exit
fi
			

back to the top

yesno-msgbox shell script

download

#!/bin/bash

CD="$HOME/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog"

### Example 1
rv=`$CD yesno-msgbox --no-cancel --string-output --no-newline \
    --text  "This is a simple first example" \
    --informative-text "We're just going to echo the string output"`
echo "User pressed the $rv button"

### Example 2
rv=`$CD yesno-msgbox --text "Do you like CocoaDialog?"`
if [ "$rv" == "1" ]; then
    echo "User likes this program"
elif [ "$rv" == "2" ]; then
    echo "User does not like this program"
elif [ "$rv" == "3" ]; then
    echo "User has no opinion (pressed cancel)"
fi
			

back to the top

msgbox shell script

download

#!/bin/bash

CD="$HOME/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog"

rv=`$CD msgbox --no-newline \
    --text "What's your favorite OS?" \
    --informative-text "The 'Cancel' label auto-binds that button to esc" \
    --button1 "OS X" --button2 "GNU/Linux" --button3 "Cancel"`
if [ "$rv" == "1" ]; then
    echo "User likes Macs"
elif [ "$rv" == "2" ]; then
    echo "User likes Linux"
elif [ "$rv" == "3" ]; then
    echo "User doesn't care"
fi
			

back to the top

standard-inputbox Perl script

download

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

our $CD = "$ENV{HOME}/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog";

my $rv = `$CD standard-inputbox --title "Your Name" --no-newline \\
    --informative-text "Enter your name"`;

my ($button_rv, $name) = split /\n/, $rv, 2;
if ($button_rv == 1) {
    print "Hello $name\n";
} elsif ($button_rv == 2) {
    print "No name given\n";
}
			

back to the top

inputbox Perl script

download

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

our $CD = "$ENV{HOME}/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog";

my $rv = `$CD inputbox --title "Search" --no-newline \\
    --informative-text "Enter your search term" \\
    --text "foobar" \\
    --button1 "Search" --button2 "Search all" \\
    --width 600`;

my ($button_rv, $term) = split /\n/, $rv, 2;
if ($button_rv == 1) {
    print "Search for '$term'\n";
} elsif ($button_rv == 2) {
    print "Search all files for '$term'\n";
}
			

back to the top

progressbar Python class

Paul Bissex wrote this Python class for working with the progressbar control

download

"""ProgressBar -- for use with CocoaDialog (http://cocoadialog.sourceforge.net/)"""

__author__ = "Paul Bissex <pb@e-scribe.com>"
__version__ = "0.2.1"
__license__ = "MIT"

import os

class ProgressBar:
    """Simple class for displaying progress bars using CocoaDialog"""

    # Change CD_BASE to reflect the location of Cocoadialog on your system
    CD_BASE = "/Library/Application\ Support"
    CD_PATH = os.path.join(CD_BASE, "CocoaDialog.app/Contents/MacOS/CocoaDialog")
    
    def __init__(self, title="Progress", message="", percent=0):
        """Create progress bar dialog"""
        template = "%s progressbar --title '%s' --text '%s' --percent %d"
        self.percent = percent
        self.pipe = os.popen(template % (ProgressBar.CD_PATH, title, message, percent), "w")
        self.message = message
            
    def update(self, percent, message=False):
        """Update progress bar (and message if desired)"""
        if message:
            self.message = message  # store message for persistence
        self.pipe.write("%d %s\n" % (percent, self.message))
        self.pipe.flush()
        
    def finish(self):
        """Close progress bar window"""
        self.pipe.close()


if __name__ == "__main__":
    # Sample usage
    import time
    bar = ProgressBar(title="ProgressBar.py Test")
    
    for percent in range(25):
        time.sleep(.15)
        bar.update(percent, "Test Starting...")
        
    for percent in range(25,100):
        time.sleep(.02)
        bar.update(percent, "Test Finishing...")
     
    time.sleep(.5)
    bar.finish()
			

back to the top

progressbar Perl script

download

#!/usr/bin/perl -w

use strict;
use IO::File;

our $COCOA_DIALOG = "$ENV{HOME}/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog";
die "$COCOA_DIALOG doesn't exist" unless -e $COCOA_DIALOG;

###
### EXAMPLE 1
###

### Open a pipe to the program
my $fh = IO::File->new("|$COCOA_DIALOG progressbar");
die "no fh" unless defined $fh;
$fh->autoflush(1);

my $percent = 0;
for (my $percent = 0; $percent <= 100; $percent++) {
    if (!($percent % 5)) {
        ### Update the progressbar and its label every 5%
        print $fh "$percent we're at $percent%\n";
    } else {
        ### Update the progressbar every percent
        print $fh "$percent\n";
    }
    ### simulate a long operation
    1 for (0 .. 90_000);
}

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

###
### EXAMPLE 2
###

### Now let's do an indeterminate one
$fh = IO::File->new("|$COCOA_DIALOG progressbar --indeterminate");
die "no fh" unless defined $fh;
$fh->autoflush(1);

### Just loop an arbitrary number of times to simulate something taking
### a long time
for (0 .. 1_500_000) {
    ### Update the label every once and a while.
    if (!($_ % 300_000)) {
        my @msgs = ('Still going', 'This might take a while',
            'Please be patient', 'Who knows how long this will take');
        my $msg = @msgs[rand @msgs];
        ### It does not matter what percent you use on an indeterminate
        ### progressbar.  We're using 0
        print $fh "0 $msg\n";
    }
}

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

###
### EXAMPLE 3
###

### Here's a more practical example of using an indeterminate progressbar
my $args = '--title "Working..." --text "This will take a while"';
$fh = IO::File->new("|$COCOA_DIALOG progressbar --indeterminate $args");
die "no fh" unless defined $fh;
$fh->autoflush(1);

# Do your really long operation here.
sleep 8;

$fh->close();
			

back to the top

progressbar shell script

Thanks to Kevin Hendricks for writing this and sending it in.
download

#!/bin/bash

# create a named pipe
rm -f /tmp/hpipe
mkfifo /tmp/hpipe

# create a background job which takes its input from the named pipe
~/Desktop/CocoaDialog.app/Contents/MacOS/CocoaDialog progressbar \
	--indeterminate --title "My Program" \
	--text "Please wait..." < /tmp/hpipe &

# associate file descriptor 3 with that pipe and send a character through the pipe
exec 3<> /tmp/hpipe
echo -n . >&3

# do all of your work here
sleep 20

# now turn off the progress bar by closing file descriptor 3
exec 3>&-

# wait for all background jobs to exit
wait
rm -f /tmp/hpipe
exit 0
			

back to the top

Ideas and help for working with the progressbar

Written by Allan Odgaard

In bash (and probably other shells) >(command) runs 'command' (in a sub process) and replaces the statement with a file handle (named pipe), so by using that (called process substitution) we can make the shell do the bookkeeping, which was manual in the example at the page (i.e. the shell will create the named pipe, and close it, when our command closes its output, which happens when the command completes).

So for the percantage, we can settle with:

    for (( i = 1; i <= 100; i++ )); do
        echo "$i We're now at $i%"; sleep .05
    done > >(CocoaDialog progressbar --title "My Program")
		

If we need to run several commands, we can use a block like this:

    {   command1
        command2
        command3
    } > >(CocoaDialog progressbar --indeterminate --title "My Program"))
		

And if we need a result back from the block of commands, we can redirect stderr instead of stdout, example:

    res=$({
        sleep 5
        echo "That's all folks!"
    } 2> >(CocoaDialog progressbar --indeterminate --title "My Program"))

    echo "Got back: $res"
		

back to the top

textbox Perl script

download

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

our $CD = "$ENV{HOME}/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog";

my $rv;

### Non-editable example
if (-e "COPYING") {
    $rv = `$CD textbox --title "License" --no-newline \\
        --informative-text "Do you agree with the terms of this license?" \\
        --text-from-file COPYING --button1 Ok --button2 Cancel`;
} else {
    $rv = `$CD textbox --title "License" --no-newline \\
        --informative-text "Do you agree with the terms of this license?" \\
        --text "This is the text of the license...." \\
        --button1 Ok --button2 Cancel`;
}
if ($rv == 1) {
    print "User agrees\n";
} else {
    print "User canceled\n";
}

### Editable example
$rv = `$CD textbox --title "Tell me a story" \\
    --informative-text "Write up a story..." \\
    --button1 "Echo" \\
    --button2 "Cancel" \\
    --text "Whatever you want" \\
    --selected \\
    --scroll-top top \\
    --editable`;
# First line is the button value, the rest is the textbox
my ($button_rv, $text) = split /\n/, $rv, 2;
if ($button_rv == 1) {
    print $text;
} elsif ($button_rv == 2) {
    print "User hit cancel\n";
}
			

back to the top

fileselect shell script

download

#!/bin/bash

CD="$HOME/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog"

### Example 1
rv=`$CD fileselect \
    --text "Choose the source file for the main controller" \
    --with-extensions .c .m .cpp`
if [ -n "$rv" ]; then  ### if $rv has a non-zero length
    echo "Main source: $rv"
else
    echo "No source file selected"
fi

### Example 2
rv=`$CD fileselect \
    --text "Pick some files and/or directories" \
    --with-directory $HOME/Documents/ \
    --select-directories \
    --select-multiple`
if [ -n "$rv" ]; then
    ### Loop over lines returned by fileselect
    echo -e "$rv" | while read file; do
        ### Check if it's a directory
        if [ -d "$file" ]; then
            echo "Directory: $file"
        ### Else a regular file
        elif [ -e "$file" ]; then
            echo "Regular file: $file"
        fi
    done
else
    echo "No files chosen"
fi
			

back to the top

dropdown Perl script

download

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

our $CD = "$ENV{HOME}/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog";

my $rv = `$CD dropdown --title "Preferred OS" --no-newline \\
	---text "What is your favorite OS?" \\
	--items "Mac OS X" "GNU/Linux" "Windows" --button1 'That one!' \\
	--button2 Nevermind`;
my ($button, $item) = split /\n/, $rv;

if ($button == 1) {
    print "User chose: ";
	if ($item == 0) {
		print "OS X, obviously\n";
	} elsif ($item == 1) {
		print "GNU/Linux, a fine choice\n";
	} elsif ($item == 2) {
		print "Windows?!??!?\n";
	}
} else {
    print "User canceled\n";
}
			

back to the top

Finding CocoaDialog executable

download shell script

#!/bin/bash

COCOA_DIALOG=""

if [ -d "/Applications/CocoaDialog.app" ]; then
    COCOA_DIALOG="/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog"
elif [ -d "$HOME/Applications/CocoaDialog.app" ]; then
    COCOA_DIALOG="$HOME/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog"
else
    echo "CocoaDialog.app not found"
    exit 1
fi
			

download Perl script

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

our $COCOA_DIALOG = undef;
for my $path (('/Applications', "$ENV{HOME}/Applications")) {
    if (-d "$path/CocoaDialog.app") {
        $COCOA_DIALOG = "$path/CocoaDialog.app/Contents/MacOS/CocoaDialog";
        last;
    }
}
unless (defined $COCOA_DIALOG) {
    die "Could not find CocoaDialog.app";
}
			

back to the top