MacGapProject / MacGap1

Desktop WebKit wrapper for HTML/CSS/JS applications.
Other
3.55k stars 208 forks source link

Drag and drop events? #107

Open samowitsch opened 10 years ago

samowitsch commented 10 years ago

Is it possible to throw an event with some info in JavaScript when i drop a file from Finder onto the MacGap window?

jeff-h commented 10 years ago

I think this is a very important addition to MacGap. It would need to implement three events:

as per https://developer.apple.com/library/mac/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/DragAndDrop.html#//apple_ref/doc/uid/30001233-BAJGJJAH

It would also ideally provide some way of Objective-C calling out to a JavaScript function to ask if the drag should be droppable.

See also http://stackoverflow.com/a/7073235

Are you in a position to write something to provide this? If not, I'll have to research this more as I've not done it before.

jeff-h commented 10 years ago

Alternatively, does HTML5 provide us something suitable already? For example, see http://www.html5rocks.com/en/tutorials/dnd/basics/ and http://html5demos.com/file-api

samowitsch commented 10 years ago

I will try it ^^

samowitsch commented 10 years ago

I just played a little with the HTML5 File-API. When i figured it out right the drop event has only filename, file size and mime-type as info. For security reasons the local path is not available ;-(

The next days i will take a look at the Stackoverflow link :-)

rawcreative commented 10 years ago

If you need the actual filename, you can get it by implementing:

- (void)webView: (WebView *) sender willPerformDragDestinationAction:(WebDragDestinationAction)action forDraggingInfo:(id<NSDraggingInfo>)draggingInfo

in the Webview delegate and getting the value(s) from the pasteboard. It's actually pretty straightforward.

If you want an example of how it's done take a look at https://github.com/maccman/macgap/pull/25 In fact that PR has the exact functionality you're looking for, I'm really not sure what it was never merged. I have a fork that implements a modified version of that PR that I'm working on. Ideally what I'm aiming for, is instead of needing to grab the files using macgap.file.files(), it will just return the complete file path to the drop event, and accessible via dataTransfer.files() like normal.

samowitsch commented 10 years ago

That sounds pretty cool! I appreciate a merge of #25 ;-)

jeff-h commented 10 years ago

Sorry, I admit I overlooked it due to its title and a brief read. We are adding filesystem stuff to MacGap through node-app, but this PR is actually adding something different. I'll put it on the list. I have a couple of other MacGap to-do's that I haven't had a chance to get to as yet. Hopefully this weekend.

rawcreative commented 10 years ago

While adding the node-app stuff is awesome and definitely adds alot of functionality, only implementing important features via MG/Node-app makes using MacGap a no-go for anyone that wants/needs to support anything less than OSX 10.9. It severely limits who can actually use the framework. I have two apps that I would love to port from Node-webkit to MacGap, but simply can't because I need drag/drop file support and as well as OSX 10.8 support.

jeff-h commented 10 years ago

https://github.com/maccman/macgap/pull/25 is now merged — it's in its own branch for now, as I'm awaiting some JavaScript examples on how to actually use it. I'm hoping someone will have a play with it and write some sample code, after which I will merge it with master.

liamks commented 10 years ago

@jeff-h thanks for merging this! The PR includes an update to the Readme with examples on its use. Drag-and-drop and file selection should work exactly as they do with a normal web application (in chrome or safari). The examples in the file include how to work with the array of files that drag-and-drop and file selection would yield.

jeff-h commented 10 years ago

Hey — thanks for your work on this PR!

I did try some variations of the included code i.e.

// After a user has selected files from a either `<input type='file'>`, or with drag and drop,
// their absolute paths can be obtained with
macgap.file.files();

//The following two methods will start reading the contents of a file. 
//On successful completion the 'onload' event will be triggered. 
//The 'onload' event object will contain the data from the file (event.results).

// Results in String (add  event listener to 'onload' to get results)
macgap.file.readAsText('/path/to/file');

// Results in Base64 String (add  event listener to 'onload' to get results)
macgap.file.readAsDataURL('/path/to/file');

//Available events: onerror, onload, onloadend, onloadstart
//Example:

var fileContent = function(evt){
    $("img").src = evt.result;
};

document.addEventListener('onload', fileContent, true);
macgap.file.readAsDataURL('/path/to/imag.png');

...but I was still unsure how to actually use it (I don't actually use any file related stuff myself).

Would you mind pulling in the new branch and seeing if I have merged your work correctly?

rawcreative commented 10 years ago

I haven't looked at the merged version to see if it's been changed but the original PR would've been used like this:

document.addEventListener('drop', function(e) {
    e.preventDefault();
    var files = macgap.file.files();
    //do something with the files
 }, true);

The readAsText and readAsDataURL I didn't play with but would be used after you have the list of files.

liamks commented 10 years ago

The following worked for me:

  1. create a
<input type="file" id="fileupload">

then :

      document.getElementById('fileupload').addEventListener('change', function(evt){
            var file = evt.target.files[0],
                files = macgap.file.files(), // includes full path
                file1AbsolutePath = files[0];

            macgap.file.readAsText(file1AbsolutePath);           
    }, false);

    document.addEventListener('onload', function(evt){

        document.writet(evt.result);
    }, true);

the above would print the contents of a text file to the screen. I did however run into BADEXEC.... errors. It's been a couple years since I've written any objective-c, any thoughts on why it's producing errors now (after successfully print the contents of the file).