Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Droppable app?

I can't find anything about building a droppable app (I'm on Mac but Windows and, I believe, Linux have this capability … I'm not sure it's applicable for mobile apps).

However, I'm working on a video conversion app. I want to be able to drag a video onto the app then read the path info to convert that file.

Titanium built apps seem to accept the dropped file but I haven't been able to find the path info of the dropped file.

Thanks, Mike

— asked September 8th 2010 by Mike Casto
  • desktop
  • droppable
1 Comment
  • Interesting to see that a 'standard' HTML broswer-based droppable area wouldn't work. Hmm… That's a shame.

    (I too have been looking at doing a conversion tool. I did one a while ago for Windows (but not with Titanium) using ffmpeg.exe bundled in the app)

    Recently I've been building a Mac based app with some Flash video content in it, but have run up against a (now) known bug where Flash files can be 'seen but not heard'. They're working on a WebKit fix/update to address this.

    — commented March 8th 2011 by Kosso

3 Answers

  • I figured out a solution. It's not as neat as I would have liked but it's functional - at least for Mac desktop apps.

    I would prefer a Titanium solution but until I find one this works for now.

    There's a handy little tool called "Platypus" for Mac: http://www.sveinbjorn.org/platypus

    This allows you to bundle scripts (shell, php, perl, ruby, etc.) as a Mac application.

    With Platypus I was able to do the following (I used PHP but any script that Platypus can handle could be used).

    I created a Platypus app and made it droppable, run in background, no output and doesn't remain running after execution. I then dragged my Titanium app to the resources folder.

    In the script in Platypus I grabbed the command line arguments (specifically $argv[1] in PHP … the first argument [0] is the Platypus application name) I then called to shell to execute the actual executable within the Titanium app bundle & send it that command line argument.

    Reading this it may seem complicated but, honestly, I think it took me longer to write this post than it did to build the Platypus bundle with my Titanium app.

    I built a proof of concept that you can download here: http://castoware.com/dropTest.zip

    Unzip & drag a file to the app (it has the default Platypus icon). First time you do this you'll have some of the standard first run things (i.e.: This was downloaded, are you sure you want to run it?). Also the Titanium Installer will likely run.

    All this app does is display a popup (javascript alert, specifically) of the command line argument (i.e.: the path & filename of the file you dragged to the app).

    Once you have that file info, though, you can do whatever you want with it in your Titanium app. I'm going to use this method, for instance, to put together an app that I can drag a video file to & the app ask for details (used in metadata) then convert that video file to an FLV file (with included metadata) that I can then upload to my website.

    Obviously, you can dig around in the app package and look at all the code. There's nothing real amazing or surprising.

    As I said, I would prefer a Titanium only solution for this but this will suffice for the time being.

    — answered March 8th 2011 by Mike Casto
    permalink
    0 Comments
  • This should be possible.

    I just tried it with a simple form text field (so it should be possible using other 'standard' html browser-based drag and drop solutions.)

    Add this text field (for example) to a test app:

    <form><input type='text' name='file' id='file' style='width:100px;height:50px;'></form>
    

    then drag a file in to it. You'll see that when you do, you get the file path. You could then add an onChange listener to this to tell the app code where the file is.

    hth.
    Kosso

    — answered March 8th 2011 by Kosso
    permalink
    1 Comment
    • Yup. That would work but it's not what I'm actually after. In my specific application I want to be able to drag a video file to the icon for the app (the app isn't running yet). When I drop the file on the app icon the app opens & processes the file that was dropped on the icon.

      — commented March 8th 2011 by Mike Casto
  • after playing around for many hours I found that the problem on windows is that the dataTransfer.effectAllowed property is read only meaning that you cannot set it to "copy" or "all" to indicate that you can drop files. So I have produced a work around by storing the files you are going to drop on the ondragenter event and then detecting the drop in the onmouseover event instead. The end result is that we can detect a drop of files and get hold of all of the file information. Here is a full file that will work on windows (developed using studio 2.0).

    <html>
    <head>
        <title>Drag and Drop in Titanium Desktop!</title>
        <style type="text/css">
            #holder
            {
                border: 10px dashed #ccc;
                width: 300px;
                height: 300px;
                margin: 20px auto;
            }
        </style>
        <script type="text/javascript">
            /**
             * bug fix since dataTransfer.effectAllowed seems to be read only.
             * Therefore have to "steal" data from the drag enter event and then detect a drop. 
             */
            var acceptDrop = false;
            var acceptFiles =[];
            window.onload = function () {
                var div = document.getElementById('holder');
                div.ondragenter = function (e) {
                    acceptDrop = true;
                    //acceptFiles = e.dataTransfer.files;
                    for (var i = 0; i < e.dataTransfer.files.length; i++) { // e.dataTransfer is a DataTransfer object (https://developer.mozilla.org/En/DragDrop/DataTransfer), e.dataTransfer.files is a FileList object (https://developer.mozilla.org/en/DOM/FileList)
                           var file = e.dataTransfer.files[i]; 
                           var fileInfoCopy = {};
                           for(f in file) {
                               fileInfoCopy[f] = file[f];
                        }
                        acceptFiles.push(fileInfoCopy);
                       }
                    return false;
                }
                div.onmouseout = function(e) {
                    //cancel drop since left the div
                    acceptDrop = false;          
                }
                div.onmouseover = function(e) {
                    if (acceptDrop) {
                        acceptDrop = false;
                        //once you let go of the dragged files then this event is triggered.
                        //so handle as if it was the ondrop.
                        var out = [];
                        for (var i = 0; i < acceptFiles.length; i++) { // e.dataTransfer is a DataTransfer object (https://developer.mozilla.org/En/DragDrop/DataTransfer), e.dataTransfer.files is a FileList object (https://developer.mozilla.org/en/DOM/FileList)
                            var file = acceptFiles[i]; // file is a File object (https://developer.mozilla.org/en/DOM/File)
    
                            for(f in file) {
                                out.push(f+"="+file[f]+"<br/>");
                            }
                            out.push("=====");
                            //var tiFile = Titanium.Filesystem.getFile(file.path);
                            // log the browser file
                            //console.log(file);
                            // log the Titanium wrapped version of this file, and that it exists
                            //console.log(tiFile, tiFile.exists());
                            // log the contents of the file, with '' appended to force the blob to convert to a string
                            //console.log(tiFile.read() + '');
                        }
                        document.getElementById('debug').innerHTML = out.join('');
                    }
                }
                div.ondragover = function(e) {
                    //e.preventDefault();
                    //e.dataTransfer.effectAllowed ='all';
                    //console.info('dragover:'+e.dataTransfer.effectAllowed);
                    return true;
                }
                div.ondrop = function (e) {
                    var out = [];
                    for (var i = 0; i < e.dataTransfer.files.length; i++) { // e.dataTransfer is a DataTransfer object (https://developer.mozilla.org/En/DragDrop/DataTransfer), e.dataTransfer.files is a FileList object (https://developer.mozilla.org/en/DOM/FileList)
                        var file = e.dataTransfer.files[i]; // file is a File object (https://developer.mozilla.org/en/DOM/File)
    
                        var tiFile = Titanium.Filesystem.getFile(file.path);
                        for(f in file) {
                            out.push(f+"="+file[f]+"<br/>");
                        }
                        out.push("=====");
                        // log the browser file
                        //console.log(file);
                        // log the Titanium wrapped version of this file, and that it exists
                        //console.log(tiFile, tiFile.exists());
                        // log the contents of the file, with '' appended to force the blob to convert to a string
                        //console.log(tiFile.read() + '');
                    }
                    document.getElementById('debug').innerHTML = out.join('');
                    e.preventDefault();
                    return false;
                }
            }
        </script>
    </head>
    <body>
        <div id="holder">
            Drop files here</div>
        <div id="debug"></div>
    </body>
    </html>
    
    — answered May 16th 2012 by si test
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.