CocoaDialog - Examples

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