Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
godot
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
community
godot
Commits
6a49b83e
Commit
6a49b83e
authored
May 08, 2020
by
Fabio Alessandrelli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add drop files function
parent
d2eef397
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
187 additions
and
2 deletions
+187
-2
display_server_javascript.cpp
platform/javascript/display_server_javascript.cpp
+29
-2
display_server_javascript.h
platform/javascript/display_server_javascript.h
+1
-0
javascript_main.cpp
platform/javascript/javascript_main.cpp
+1
-0
utils.js
platform/javascript/native/utils.js
+156
-0
No files found.
platform/javascript/display_server_javascript.cpp
View file @
6a49b83e
...
...
@@ -82,6 +82,25 @@ EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, co
return
false
;
}
// Drag and drop callback (see native/utils.js).
extern
"C"
EMSCRIPTEN_KEEPALIVE
void
_drop_files_callback
(
char
*
p_filev
[],
int
p_filec
)
{
DisplayServerJavaScript
*
ds
=
DisplayServerJavaScript
::
get_singleton
();
if
(
!
ds
)
{
ERR_FAIL_MSG
(
"Unable to drop files because the DisplayServer is not active"
);
}
if
(
ds
->
drop_files_callback
.
is_null
())
return
;
Vector
<
String
>
files
;
for
(
int
i
=
0
;
i
<
p_filec
;
i
++
)
{
files
.
push_back
(
String
::
utf8
(
p_filev
[
i
]));
}
Variant
v
=
files
;
Variant
*
vp
=
&
v
;
Variant
ret
;
Callable
::
CallError
ce
;
ds
->
drop_files_callback
.
call
((
const
Variant
**
)
&
vp
,
1
,
ret
,
ce
);
}
// Keys
template
<
typename
T
>
...
...
@@ -911,11 +930,12 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
/* clang-format off */
EM_ASM_ARGS
({
Module
.
listeners
=
{};
const
canvas
=
Module
[
'
canvas
'
];
const
send_window_event
=
cwrap
(
'
send_window_event
'
,
null
,
[
'
number
'
]);
const
notifications
=
arguments
;
([
'
mouseover
'
,
'
mouseleave
'
,
'
focus
'
,
'
blur
'
]).
forEach
(
function
(
event
,
index
)
{
Module
.
listeners
[
event
]
=
send_window_event
.
bind
(
null
,
notifications
[
index
]);
Module
[
'
canvas
'
]
.
addEventListener
(
event
,
Module
.
listeners
[
event
]);
canvas
.
addEventListener
(
event
,
Module
.
listeners
[
event
]);
});
// Clipboard
const
update_clipboard
=
cwrap
(
'
update_clipboard
'
,
null
,
[
'
string
'
]);
...
...
@@ -923,6 +943,13 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
update_clipboard
(
evt
.
clipboardData
.
getData
(
'
text
'
));
};
window
.
addEventListener
(
'
paste
'
,
Module
.
listeners
[
'
paste
'
],
false
);
Module
.
listeners
[
'
dragover
'
]
=
function
(
ev
)
{
// Prevent default behavior (which would try to open the file(s))
ev
.
preventDefault
();
};
Module
.
listeners
[
'
drop
'
]
=
Module
.
drop_handler
;
// Defined in native/utils.js
canvas
.
addEventListener
(
'
dragover
'
,
Module
.
listeners
[
'
dragover
'
],
false
);
canvas
.
addEventListener
(
'
drop
'
,
Module
.
listeners
[
'
drop
'
],
false
);
},
WINDOW_EVENT_MOUSE_ENTER
,
WINDOW_EVENT_MOUSE_EXIT
,
...
...
@@ -1044,7 +1071,7 @@ void DisplayServerJavaScript::window_set_input_text_callback(const Callable &p_c
}
void
DisplayServerJavaScript
::
window_set_drop_files_callback
(
const
Callable
&
p_callable
,
WindowID
p_window
)
{
// TODO this should be implemented.
drop_files_callback
=
p_callable
;
}
void
DisplayServerJavaScript
::
window_set_title
(
const
String
&
p_title
,
WindowID
p_window
)
{
...
...
platform/javascript/display_server_javascript.h
View file @
6a49b83e
...
...
@@ -91,6 +91,7 @@ public:
Callable
window_event_callback
;
Callable
input_event_callback
;
Callable
input_text_callback
;
Callable
drop_files_callback
;
// from DisplayServer
virtual
void
alert
(
const
String
&
p_alert
,
const
String
&
p_title
=
"ALERT!"
);
...
...
platform/javascript/javascript_main.cpp
View file @
6a49b83e
...
...
@@ -100,6 +100,7 @@ int main(int argc, char *argv[]) {
FS
.
syncfs
(
true
,
function
(
err
)
{
ccall
(
'
main_after_fs_sync
'
,
null
,
[
'
string
'
],
[
err
?
err
.
message
:
""
])
});
);
/* clang-format on */
...
...
platform/javascript/native/utils.js
View file @
6a49b83e
...
...
@@ -46,3 +46,159 @@ Module['copyToFS'] = function(path, buffer) {
FS
.
writeFile
(
path
,
new
Uint8Array
(
buffer
),
{
'flags'
:
'wx+'
});
}
Module
.
drop_handler
=
(
function
()
{
var
upload
=
[];
var
uploadPromises
=
[];
var
uploadCallback
=
null
;
function
readFilePromise
(
entry
,
path
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
entry
.
file
(
function
(
file
)
{
var
reader
=
new
FileReader
();
reader
.
onload
=
function
()
{
var
f
=
{
"path"
:
file
.
relativePath
||
file
.
webkitRelativePath
,
"name"
:
file
.
name
,
"type"
:
file
.
type
,
"size"
:
file
.
size
,
"data"
:
reader
.
result
};
if
(
!
f
[
'path'
])
f
[
'path'
]
=
f
[
'name'
];
upload
.
push
(
f
);
resolve
()
};
reader
.
onerror
=
function
()
{
console
.
log
(
"Error reading file"
);
reject
();
}
reader
.
readAsArrayBuffer
(
file
);
},
function
(
err
)
{
console
.
log
(
"Error!"
);
reject
();
});
});
}
function
readDirectoryPromise
(
entry
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
var
reader
=
entry
.
createReader
();
reader
.
readEntries
(
function
(
entries
)
{
for
(
var
i
=
0
;
i
<
entries
.
length
;
i
++
)
{
var
ent
=
entries
[
i
];
if
(
ent
.
isDirectory
)
{
uploadPromises
.
push
(
readDirectoryPromise
(
ent
));
}
else
if
(
ent
.
isFile
)
{
uploadPromises
.
push
(
readFilePromise
(
ent
));
}
}
resolve
();
});
});
}
function
processUploadsPromises
(
resolve
,
reject
)
{
if
(
uploadPromises
.
length
==
0
)
{
resolve
();
return
;
}
uploadPromises
.
pop
().
then
(
function
()
{
setTimeout
(
function
()
{
processUploadsPromises
(
resolve
,
reject
);
//processUploadsPromises.bind(null, resolve, reject)
},
0
);
});
}
function
dropFiles
(
files
)
{
var
args
=
files
||
[];
var
argc
=
args
.
length
;
var
argv
=
stackAlloc
((
argc
+
1
)
*
4
);
for
(
var
i
=
0
;
i
<
argc
;
i
++
)
{
HEAP32
[(
argv
>>
2
)
+
i
]
=
allocateUTF8OnStack
(
args
[
i
]);
}
HEAP32
[(
argv
>>
2
)
+
argc
]
=
0
;
// Defined in display_server_javascript.cpp
ccall
(
'_drop_files_callback'
,
'void'
,
[
'number'
,
'number'
],
[
argv
,
argc
]);
}
return
function
(
ev
)
{
ev
.
preventDefault
();
if
(
ev
.
dataTransfer
.
items
)
{
// Use DataTransferItemList interface to access the file(s)
for
(
var
i
=
0
;
i
<
ev
.
dataTransfer
.
items
.
length
;
i
++
)
{
const
item
=
ev
.
dataTransfer
.
items
[
i
];
var
entry
=
null
;
if
(
"getAsEntry"
in
item
)
{
entry
=
item
.
getAsEntry
();
}
else
if
(
"webkitGetAsEntry"
in
item
)
{
entry
=
item
.
webkitGetAsEntry
();
}
if
(
!
entry
)
{
console
.
error
(
"File upload not supported"
);
}
else
if
(
entry
.
isDirectory
)
{
uploadPromises
.
push
(
readDirectoryPromise
(
entry
));
}
else
if
(
entry
.
isFile
)
{
uploadPromises
.
push
(
readFilePromise
(
entry
));
}
else
{
console
.
error
(
"Unrecognized entry..."
,
entry
);
}
}
}
else
{
console
.
error
(
"File upload not supported"
);
}
uploadCallback
=
new
Promise
(
processUploadsPromises
).
then
(
function
()
{
const
DROP
=
"/tmp/drop-"
+
parseInt
(
Math
.
random
()
*
Math
.
pow
(
2
,
31
))
+
"/"
;
var
drops
=
[];
var
files
=
[];
upload
.
forEach
((
elem
)
=>
{
var
path
=
elem
[
'path'
];
Module
[
'copyToFS'
](
DROP
+
path
,
elem
[
'data'
]);
var
idx
=
path
.
indexOf
(
"/"
);
if
(
idx
==
-
1
)
{
// Root file
drops
.
push
(
DROP
+
path
);
}
else
{
// Subdir
var
sub
=
path
.
substr
(
0
,
idx
);
idx
=
sub
.
indexOf
(
"/"
);
if
(
idx
<
0
&&
drops
.
indexOf
(
DROP
+
sub
)
==
-
1
)
{
drops
.
push
(
DROP
+
sub
);
}
}
files
.
push
(
DROP
+
path
);
});
uploadPromises
=
[];
upload
=
[];
dropFiles
(
drops
);
var
dirs
=
[
DROP
.
substr
(
0
,
DROP
.
length
-
1
)];
files
.
forEach
(
function
(
file
)
{
FS
.
unlink
(
file
);
var
dir
=
file
.
replace
(
DROP
,
""
);
var
idx
=
dir
.
lastIndexOf
(
"/"
);
while
(
idx
>
0
)
{
dir
=
dir
.
substr
(
0
,
idx
);
if
(
dirs
.
indexOf
(
DROP
+
dir
)
==
-
1
)
{
dirs
.
push
(
DROP
+
dir
);
}
idx
=
dir
.
lastIndexOf
(
"/"
);
}
});
// Remove dirs.
dirs
=
dirs
.
sort
(
function
(
a
,
b
)
{
var
al
=
(
a
.
match
(
/
\/
/g
)
||
[]).
length
;
var
bl
=
(
b
.
match
(
/
\/
/g
)
||
[]).
length
;
if
(
al
>
bl
)
return
-
1
;
else
if
(
al
<
bl
)
return
1
;
return
0
;
});
dirs
.
forEach
(
function
(
dir
)
{
FS
.
rmdir
(
dir
);
});
});
}
})();
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment