Droplets

What is a droplet?

It is a way to drag and drop a file(s) or directory(ies) onto a tcl program which can then pick up the file/directory names using the standard argc and argv command line argument variables.


ET Here is how one goes about this on windows (w2k and up, not w9x):

Create a text file with a .bat extention (cp. DOS BAT magic), and prefix the tcl code with

 ::if 0 {
 start wish "%~f0" %* 
 exit
 }
 Tcl/tk code follows....

Note: This assumes you have wish in your path. If you install ActiveState's tcl/tk, this should set the path for you.

AET 12apr06 If you want to use TclKit.exe instead of wish, a little jiggery pokery is required, because you cannot use

 tclkit myScript myArguments

the myArguments are simply lost.

LV 2009Apr22 - Current tclkits do not have the problem with arguments described above.

I save the list to an environment variable, then pick it up again within Tcl. For example;

 ::if 0 {FIRST THE BATCH SCRIPT
   @echo off
   if not {%1}=={} (
     set myFiles=%*
     start /min tclkit "%~f0"
     exit
   ) else (
     echo No arguments supplied; You probably didn't drop any files onto the batch file.
     pause & exit
   )
 }
 # NOW TCL STARTS
 wm wi .
 foreach f [string map {\\ \\\\} $env(MYFILES)] {append fileList "\n" $f}
 tk_messageBox -message "You dropped these files: $fileList"
 exit

NOTES:

The batch script sets an environment variable (only within it's own shell) which is lost when it closes. The variable is a space delimited list (quoted to preserve spaces) of dropped files. Another shell is started within this shell before it closes, so inherits the environment. Tclkit - started within this child shell - can read it with $env(MYFILES). Note that the variable name must be capitalised, regardless of the case in the saved variable.

Of course, a minimal script only needs lines 4,5,6; I prefer the minimal;

  if not {%1}=={} @echo off & set myFiles=%* & start /min tclkit "%~f0" & exit

The /min switch tends to minimise the ugly DOS box that briefly appears.

Note the exit at the end of Tcl. if you leave this out, the instance of tcl will not close. You will see see them accumulate in your process list in Task Manager.


Here are 3 examples,


argtest.bat

This is my latest template. It handles both dnd but also could be run from the command line, which is useful if you are exec'ing it. I borrowed code that figures out which way it was started, and either exits if dnd, or if run from cmd, it leaves the cmd window open. It closes the . window, so it sets up an exit on the console close.

::if 0 {
    start wish "%~f0" %* 
    @echo off
    for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1
    IF defined DOUBLECLICKED (
        exit
    ) ELSE (
        cmd /k
    )
:: }
wm wi .
console show
console eval {wm geom . 146x13+128+128; wm protocol . WM_DELETE_WINDOW exit }
if {$argc > 0} {
    puts "argc = |$argc| "
    foreach arg $argv {
        set type "-"
        if       { [file isdirectory $arg] } {
            set type "D"
        } elseif { [file readable $arg] } {
            set type "F"
        }
        puts "arg [incr n] = $type |$arg| "
    }
} else {
    puts stderr "No arguments found"
}

2clip.bat

This simply lets one drag/drop a file onto the batch file and the full path to the file is placed into the clipboard. It will put up a dialog box because the clipboard gets cleared when the program exits. It will also just quit in 30 seconds as well. So, before the 30 seconds are up, you can paste the full name of the file into, say, a console windows.

 ::if 0 {
 start wish "%~f0" %* & exit
 }
 wm wi .
 if {$argc > 0} {
         clipboard clear
         set f [lindex $argv 0]
         clipboard append $f
         after 30000 exit
         tk_messageBox -message "Clipboard:\n$f" 
 }
 exit

pic2tcl.bat

Drag/drop a .gif or .jpg file(s) onto the batch file and it will create a file of the same path and name but with a .tcl extension that can be used as an inline image.

 ::if 0 {
 start wish "%~f0" %* & exit
 }
   package require base64
   proc trans {arg} {

     set file $arg

     set fd [open $file r]
     fconfigure $fd -translation binary
     set rawdata [read $fd]
     close $fd
     set fd [open [file root $arg].tcl w]
     set b64data [base64::encode $rawdata]
     puts $fd "image create photo -data {\n$b64data\n}"
     close $fd
   }


  wm wi .
  
  if {$argc > 0} {
    foreach f $argv {
      set f [file normalize $f]
      #tk_messageBox -message "Doing something with \n$f"
      trans $f
    }
  }
  tk_messageBox -message Done.
  exit

PR I chose a two files approach to turn Tcl/Tk scripts into Droplets on Windows (XP). The BAT file is very compact:

Gray2Jpeg.bat

  @echo off

  C:
  chdir %HOMEPATH%\Desktop
  chdir

  start "Gray2Jpeg" /B "%HOMEDRIVE%%HOMEPATH%\hier\bin\Gray2Jpeg.tcl" %1

All meaningful things happen in the TCL file, in this example Gray2Jpeg.tcl on Image Magick.


anoved: If defined, the ::tk::mac::OpenDocument procedure will be called with a list of files dropped on your Mac application's icon. See section 2.2 of the New Tcl/TkAqua FAQ. This procedure is also called in response to other "open document" events, such as when a file associated with your application is double-clicked in the Finder.