From fed6eda6761527fdde4a537810600a0578571c55 Mon Sep 17 00:00:00 2001 From: Yanrishatum Date: Sun, 30 Jan 2022 17:56:00 +0300 Subject: [PATCH 1/4] Draft of Drag&Drop support JS implementation for Drag&Drop --- hxd/DropFileEvent.hx | 124 +++++++++++++++++++++++++++++++++++++++++++ hxd/Window.hx | 6 +++ hxd/Window.js.hx | 96 +++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 hxd/DropFileEvent.hx diff --git a/hxd/DropFileEvent.hx b/hxd/DropFileEvent.hx new file mode 100644 index 000000000..212beb35e --- /dev/null +++ b/hxd/DropFileEvent.hx @@ -0,0 +1,124 @@ +package hxd; + +import haxe.io.Bytes; + +/** + The Drag&Drop event type. + + @see `hxd.DropFileEvent.kind` +**/ +enum DropFileEventKind { + /** + User initiated the drag&drop operation by dragging content over the window. + **/ + DropStart; + /** + User cancelled the drag&drop operation by moving cursor outside the window area. + **/ + DropEnd; + /** + User continued the drag&drop operation by moving the cursor within the window area. + **/ + DropMove; + /** + User confirmed the drag&drop operation. + **/ + Drop; +} + +/** + The type of the content that was drag&dropped by user. + + @see `DroppedFile.kind` +**/ +enum DropFileContentKind { + /** + The dropped file contents is a string. + **/ + KString; + /** + The dropped file contents is a binary file. + **/ + KFile; + /** + The dropped file contents are an unsupported type. + **/ + KUnknown(type: String); +} + +/** + The information about the dropped file. +**/ +interface DroppedFile { + /** + The content type of the dropped file. + **/ + var kind : DropFileContentKind; + /** + The dropped file name if available. + **/ + var name : String; + /** + The dropped file MIME type if available. + **/ + var type : String; + + /** + Retrieve the dropped file contents as Bytes and pass it to `callback`. + **/ + function getBytes( callback : (data : Bytes) -> Void ) : Void; + /** + Retrieve the dropped file contents as a String and pass to to `callback`. + **/ + function getString( callback : (data : String) -> Void ) : Void; + + /** + Return the native file information data. + **/ + // function getNative() + + #if !js + /** + [non-`js` target only] Returns the contents of the dropped file as Bytes. + **/ + function getBytesSync() : Bytes; + /** + [non-`js` target only] Returns the contents of the dropped file as a String. + **/ + function getStringSync() : String; + #end + +} + +/** + The drag&drop operation event. + + @see `hxd.Window.addDragAndDropTarget` + @see `hxd.Window.removeDragAndDropTarget` +**/ +class DropFileEvent { + /** + The event type of the drag&drop operation. + **/ + public var kind: DropFileEventKind; + + /** + The list of the files that were dropped. + + Only guaranteed to be populated when `kind == Drop`. + **/ + public var files: Array; + /** + The first dropped file. Alias to `files[0]`. + **/ + public var file(get, never): Null; + + public function new(kind: DropFileEventKind, files: Array) { + this.kind = kind; + this.files = files; + } + + inline function get_file() return files[0]; + +} + diff --git a/hxd/Window.hx b/hxd/Window.hx index 7ff482bff..95feafcfe 100644 --- a/hxd/Window.hx +++ b/hxd/Window.hx @@ -68,6 +68,12 @@ class Window { public function resize( width : Int, height : Int ) : Void { } + public function addDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { + } + + public function removeDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { + } + @:deprecated("Use the displayMode property instead") public function setFullScreen( v : Bool ) : Void { } diff --git a/hxd/Window.js.hx b/hxd/Window.js.hx index b6abd48fa..eaca8bacf 100644 --- a/hxd/Window.js.hx +++ b/hxd/Window.js.hx @@ -7,10 +7,58 @@ enum DisplayMode { FullscreenResize; } +private class NativeDroppedFile implements hxd.DropFileEvent.DroppedFile { + + public var kind : hxd.DropFileEvent.DropFileContentKind; + public var name : String; + public var type : String; + + var item : js.html.DataTransferItem; + + public function new( item : js.html.DataTransferItem ) { + this.item = item; + if (item.kind == "file") { + var file = item.getAsFile(); + this.name = file.name; + this.type = file.type; + } else { + this.name = ""; + this.type = item.type; + } + } + + public function getBytes( callback : ( data : haxe.io.Bytes ) -> Void ) { + if (item.kind == "file") { + var file = item.getAsFile(); + var reader = new js.html.FileReader(); + // TODO: Make sure no errors happen. + reader.onload = (_) -> callback(haxe.io.Bytes.ofData(reader.result)); + reader.readAsArrayBuffer(file); + } else { + item.getAsString(( str : String ) -> callback(haxe.io.Bytes.ofString(str)) ); + } + } + + public function getString( callback : ( data : String ) -> Void ) { + if (item.kind == "file") { + var file = item.getAsFile(); + var reader = new js.html.FileReader(); + // TODO: Make sure no errors happen. + reader.onload = (_) -> callback(reader.result); + reader.readAsText(file); + } else { + item.getAsString(( str : String ) -> callback(str) ); + } + } + +} + class Window { var resizeEvents : List Void>; var eventTargets : List Void>; + var dropTargets : List Void>; + var dropDragEvent: DropFileEvent = new DropFileEvent(DropMove, null); // Reused drag event when dragging over time. public var width(get, never) : Int; public var height(get, never) : Int; @@ -48,6 +96,7 @@ class Window { var customCanvas = canvas != null; eventTargets = new List(); resizeEvents = new List(); + dropTargets = new List(); if( !js.Browser.supported ) { canvasPos = { "width":0, "top":0, "left":0, "height":0 }; @@ -194,6 +243,53 @@ class Window { public function resize( width : Int, height : Int ) : Void { } + public function addDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { + if( dropTargets.length == 0 ) { + var element = canvas; // Probably should adhere to `globalEvents`? + element.addEventListener("dragenter", handleDragAndDropEvent); + element.addEventListener("dragleave", handleDragAndDropEvent); + element.addEventListener("dragover", handleDragAndDropEvent); + element.addEventListener("drop", handleDragAndDropEvent); + } + dropTargets.add(f); + } + + public function removeDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { + for( e in dropTargets ) + if( Reflect.compareMethods(e, f) ) { + dropTargets.remove(f); + break; + } + if( dropTargets.length == 0 ) { + var element = canvas; // Probably should adhere to `globalEvents`? + element.removeEventListener("dragenter", handleDragAndDropEvent); + element.removeEventListener("dragleave", handleDragAndDropEvent); + element.removeEventListener("dragover", handleDragAndDropEvent); + element.removeEventListener("drop", handleDragAndDropEvent); + } + } + + function handleDragAndDropEvent( e : js.html.DragEvent ) { + var files : Array = []; + // TODO: Don't allocate dropped file every time, only when it changes. + if( e.dataTransfer != null ) + for( i in 0...e.dataTransfer.items.length ) + files.push(new NativeDroppedFile(e.dataTransfer.items[i])); + var ev = switch( e.type ) { + case "dragenter": + new DropFileEvent(DropStart, files); + case "dragleave": + new DropFileEvent(DropEnd, files); + case "drop": + new DropFileEvent(Drop, files); + case "dragover": + dropDragEvent.files = files; + dropDragEvent; + default: throw "assert"; + } + for( e in dropTargets ) e(ev); + } + @:deprecated("Use the displayMode property instead") public function setFullScreen( v : Bool ) : Void { var doc = js.Browser.document; From fc7ed07b9295a0553e752220f49494120006f280 Mon Sep 17 00:00:00 2001 From: Yanrishatum Date: Mon, 31 Jan 2022 12:45:56 +0300 Subject: [PATCH 2/4] Implement drag&drop for HLSDL --- hxd/DropFileEvent.hx | 9 ++++++ hxd/Window.hl.hx | 76 ++++++++++++++++++++++++++++++++++++++++++++ hxd/Window.hx | 6 ++++ 3 files changed, 91 insertions(+) diff --git a/hxd/DropFileEvent.hx b/hxd/DropFileEvent.hx index 212beb35e..f3db83c10 100644 --- a/hxd/DropFileEvent.hx +++ b/hxd/DropFileEvent.hx @@ -10,14 +10,20 @@ import haxe.io.Bytes; enum DropFileEventKind { /** User initiated the drag&drop operation by dragging content over the window. + + Only fired if `DropFileEvent.SupportsOngoingEvent` is `true`. **/ DropStart; /** User cancelled the drag&drop operation by moving cursor outside the window area. + + Only fired if `DropFileEvent.SupportsOngoingEvent` is `true`. **/ DropEnd; /** User continued the drag&drop operation by moving the cursor within the window area. + + Only fired if `DropFileEvent.SupportsOngoingEvent` is `true`. **/ DropMove; /** @@ -97,6 +103,9 @@ interface DroppedFile { @see `hxd.Window.removeDragAndDropTarget` **/ class DropFileEvent { + + public static inline var SupportsOngoingEvent = #if js true #else false #end ; + /** The event type of the drag&drop operation. **/ diff --git a/hxd/Window.hl.hx b/hxd/Window.hl.hx index 7a9890682..a011b550c 100644 --- a/hxd/Window.hl.hx +++ b/hxd/Window.hl.hx @@ -29,11 +29,46 @@ typedef DisplaySetting = { framerate : Int } +private class NativeDroppedFile implements hxd.DropFileEvent.DroppedFile { + + public var kind : hxd.DropFileEvent.DropFileContentKind; + public var name : String; + public var type : String; + + public function new( kind : hxd.DropFileEvent.DropFileContentKind, name : String ) { + this.kind = kind; + this.name = name; + this.type = ""; + } + + public function getBytes( callback : ( data : haxe.io.Bytes ) -> Void ) { + haxe.Timer.delay(() -> callback(getBytesSync()), 1); + } + + public function getString( callback : ( data : String ) -> Void ) { + haxe.Timer.delay(() -> callback(getStringSync()), 1); + } + + public function getBytesSync() : haxe.io.Bytes { + return + if (kind == KString) haxe.io.Bytes.ofString(name); + else sys.io.File.getBytes(name); + } + + public function getStringSync():String { + return + if (kind == KString) name; + else sys.io.File.getContent(name); + } +} + //@:coreApi class Window { var resizeEvents : List Void>; var eventTargets : List Void>; + var dropTargets : List Void>; + var dropFiles : Array; public var width(get, never) : Int; public var height(get, never) : Int; @@ -77,6 +112,7 @@ class Window { this.windowHeight = height; eventTargets = new List(); resizeEvents = new List(); + dropTargets = new List(); #if hlsdl var sdlFlags = if (!fixed) sdl.Window.SDL_WINDOW_SHOWN | sdl.Window.SDL_WINDOW_RESIZABLE else sdl.Window.SDL_WINDOW_SHOWN; #if heaps_vulkan @@ -149,6 +185,34 @@ class Window { for( f in resizeEvents ) f(); } + public function addDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { + dropTargets.push(f); + #if (hl_ver >= version("1.12.0")) + #if hlsdl + sdl.Sdl.setDragAndDropEnabled(true); + #elseif hldx + + #end + #end + } + + public function removeDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { + for( e in dropTargets ) + if( Reflect.compareMethods(e, f) ) { + dropTargets.remove(f); + break; + } + if ( dropTargets.length == 0 ) { + #if (hl_ver >= version("1.12.0")) + #if hlsdl + sdl.Sdl.setDragAndDropEnabled(false); + #elseif hldx + + #end + #end + } + } + @:deprecated("Use the displayMode property instead") public function setFullScreen( v : Bool ) : Void { #if (hldx || hlsdl) @@ -316,6 +380,18 @@ class Window { #end eh = new Event(ERelease, e.mouseX, e.mouseY); eh.touchId = e.fingerId; + #if (hl_ver >= version("1.12.0")) + case DropStart: + dropFiles = []; + case DropFile: + dropFiles.push(new NativeDroppedFile(KFile, @:privateAccess String.fromUTF8(e.dropFile))); + case DropText: + dropFiles.push(new NativeDroppedFile(KString, @:privateAccess String.fromUTF8(e.dropFile))); + case DropEnd: + for ( dt in dropTargets ) dt(new DropFileEvent(Drop, dropFiles)); + dropFiles = null; + #end + #elseif hldx case KeyDown: eh = new Event(EKeyDown); diff --git a/hxd/Window.hx b/hxd/Window.hx index 95feafcfe..520400f45 100644 --- a/hxd/Window.hx +++ b/hxd/Window.hx @@ -68,9 +68,15 @@ class Window { public function resize( width : Int, height : Int ) : Void { } + /** + Add a drag&drop events callback. + **/ public function addDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { } + /** + Remove a drag&drop events callback. + **/ public function removeDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { } From fca16d57a0b1fa653d224a9a4bcc38be2d589a5f Mon Sep 17 00:00:00 2001 From: Yanrishatum Date: Sun, 5 Nov 2023 16:30:35 +0300 Subject: [PATCH 3/4] Update D&D implementation Added hldx/hlsdl support Removed ongoing events (only drop action handled) Removed string/file distinction (now only files are supported) Removed synchronous API Added dropX/dropY fields to drop event Change drop event from interface to abstract --- hxd/DropFileEvent.hx | 121 +++++++++++-------------------------------- hxd/Window.hl.hx | 85 ++++++++++++------------------ hxd/Window.js.hx | 77 +++++---------------------- 3 files changed, 77 insertions(+), 206 deletions(-) diff --git a/hxd/DropFileEvent.hx b/hxd/DropFileEvent.hx index f3db83c10..0a421a950 100644 --- a/hxd/DropFileEvent.hx +++ b/hxd/DropFileEvent.hx @@ -1,99 +1,37 @@ package hxd; +import haxe.ds.ReadOnlyArray; import haxe.io.Bytes; -/** - The Drag&Drop event type. - - @see `hxd.DropFileEvent.kind` -**/ -enum DropFileEventKind { - /** - User initiated the drag&drop operation by dragging content over the window. - - Only fired if `DropFileEvent.SupportsOngoingEvent` is `true`. - **/ - DropStart; - /** - User cancelled the drag&drop operation by moving cursor outside the window area. - - Only fired if `DropFileEvent.SupportsOngoingEvent` is `true`. - **/ - DropEnd; - /** - User continued the drag&drop operation by moving the cursor within the window area. - - Only fired if `DropFileEvent.SupportsOngoingEvent` is `true`. - **/ - DropMove; - /** - User confirmed the drag&drop operation. - **/ - Drop; -} - -/** - The type of the content that was drag&dropped by user. - - @see `DroppedFile.kind` -**/ -enum DropFileContentKind { - /** - The dropped file contents is a string. - **/ - KString; - /** - The dropped file contents is a binary file. - **/ - KFile; - /** - The dropped file contents are an unsupported type. - **/ - KUnknown(type: String); -} - /** The information about the dropped file. **/ -interface DroppedFile { - /** - The content type of the dropped file. - **/ - var kind : DropFileContentKind; +abstract class DroppedFile { /** - The dropped file name if available. + The dropped file name/path. **/ - var name : String; + public var file(default, null) : String; + #if js /** - The dropped file MIME type if available. + The native JS data transfer file. **/ - var type : String; + public var native(default, null) : js.html.File; - /** - Retrieve the dropped file contents as Bytes and pass it to `callback`. - **/ - function getBytes( callback : (data : Bytes) -> Void ) : Void; - /** - Retrieve the dropped file contents as a String and pass to to `callback`. - **/ - function getString( callback : (data : String) -> Void ) : Void; + public function new( native : js.html.File ) { + this.file = native.name; + this.native = native; + } + #else + public function new( file : String ) { + this.file = file; + } + #end - /** - Return the native file information data. - **/ - // function getNative() - #if !js /** - [non-`js` target only] Returns the contents of the dropped file as Bytes. + Retrieve the dropped file contents asynchronously and pass it to `callback`. **/ - function getBytesSync() : Bytes; - /** - [non-`js` target only] Returns the contents of the dropped file as a String. - **/ - function getStringSync() : String; - #end - + abstract public function getBytes( callback : (data : Bytes) -> Void ) : Void; } /** @@ -103,28 +41,29 @@ interface DroppedFile { @see `hxd.Window.removeDragAndDropTarget` **/ class DropFileEvent { - - public static inline var SupportsOngoingEvent = #if js true #else false #end ; - - /** - The event type of the drag&drop operation. - **/ - public var kind: DropFileEventKind; - /** The list of the files that were dropped. Only guaranteed to be populated when `kind == Drop`. **/ - public var files: Array; + public var files(default, null): ReadOnlyArray; /** The first dropped file. Alias to `files[0]`. **/ public var file(get, never): Null; + /** + The X position inside the window at which the file was dropped. + **/ + public var dropX(default, null): Int; + /** + The Y position inside the window at which the file was dropped. + **/ + public var dropY(default, null): Int; - public function new(kind: DropFileEventKind, files: Array) { - this.kind = kind; + public function new( files : Array, dx : Int, dy : Int ) { this.files = files; + this.dropX = dx; + this.dropY = dy; } inline function get_file() return files[0]; diff --git a/hxd/Window.hl.hx b/hxd/Window.hl.hx index 67d958f61..15c535947 100644 --- a/hxd/Window.hl.hx +++ b/hxd/Window.hl.hx @@ -30,36 +30,9 @@ typedef DisplaySetting = { framerate : Int } -private class NativeDroppedFile implements hxd.DropFileEvent.DroppedFile { - - public var kind : hxd.DropFileEvent.DropFileContentKind; - public var name : String; - public var type : String; - - public function new( kind : hxd.DropFileEvent.DropFileContentKind, name : String ) { - this.kind = kind; - this.name = name; - this.type = ""; - } - +private class NativeDroppedFile extends hxd.DropFileEvent.DroppedFile { public function getBytes( callback : ( data : haxe.io.Bytes ) -> Void ) { - haxe.Timer.delay(() -> callback(getBytesSync()), 1); - } - - public function getString( callback : ( data : String ) -> Void ) { - haxe.Timer.delay(() -> callback(getStringSync()), 1); - } - - public function getBytesSync() : haxe.io.Bytes { - return - if (kind == KString) haxe.io.Bytes.ofString(name); - else sys.io.File.getBytes(name); - } - - public function getStringSync():String { - return - if (kind == KString) name; - else sys.io.File.getContent(name); + haxe.Timer.delay(() -> callback(sys.io.File.getBytes(file)), 1); } } @@ -205,14 +178,14 @@ class Window { } public function addDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { + if (dropTargets.length == 0) { + #if (hlsdl >= version("1.14.0")) + sdl.Sdl.setDragAndDropEnabled(true); + #elseif (hldx >= version("1.14.0")) + window.dragAndDropEnabled = true; + #end + } dropTargets.push(f); - #if (hl_ver >= version("1.13.0")) - #if hlsdl - sdl.Sdl.setDragAndDropEnabled(true); - #elseif hldx - - #end - #end } public function removeDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { @@ -222,12 +195,10 @@ class Window { break; } if ( dropTargets.length == 0 ) { - #if (hl_ver >= version("1.13.0")) - #if hlsdl + #if (hlsdl >= version("1.14.0")) sdl.Sdl.setDragAndDropEnabled(false); - #elseif hldx - - #end + #elseif (hldx >= version("1.14.0")) + window.dragAndDropEnabled = false; #end } } @@ -503,17 +474,6 @@ class Window { #end eh = new Event(ERelease, e.mouseX, e.mouseY); eh.touchId = e.fingerId; - #if (hl_ver >= version("1.12.0")) - case DropStart: - dropFiles = []; - case DropFile: - dropFiles.push(new NativeDroppedFile(KFile, @:privateAccess String.fromUTF8(e.dropFile))); - case DropText: - dropFiles.push(new NativeDroppedFile(KString, @:privateAccess String.fromUTF8(e.dropFile))); - case DropEnd: - for ( dt in dropTargets ) dt(new DropFileEvent(Drop, dropFiles)); - dropFiles = null; - #end #elseif hldx case KeyDown: @@ -534,6 +494,27 @@ class Window { eh = new Event(ETextInput, mouseX, mouseY); eh.charCode = e.keyCode; #end + #if (hlsdl >= version("1.14.0") || hldx >= version("1.14.0")) + case DropStart: + dropFiles = []; + case DropFile: + #if hlsdl + dropFiles.push(new NativeDroppedFile(@:privateAccess String.fromUTF8(e.dropFile))); + #else + dropFiles.push(new NativeDroppedFile(@:privateAccess String.fromUCS2(e.dropFile))); + #end + case DropEnd: + var event = new DropFileEvent( + dropFiles, + #if hldx + e.mouseX, e.mouseY + #else + mouseX, mouseY + #end + ); + for ( dt in dropTargets ) dt(event); + dropFiles = null; + #end case Quit: return onClose(); default: diff --git a/hxd/Window.js.hx b/hxd/Window.js.hx index e4e436b04..b9b81d9b8 100644 --- a/hxd/Window.js.hx +++ b/hxd/Window.js.hx @@ -10,48 +10,13 @@ enum DisplayMode { FullscreenResize; } -private class NativeDroppedFile implements hxd.DropFileEvent.DroppedFile { - - public var kind : hxd.DropFileEvent.DropFileContentKind; - public var name : String; - public var type : String; - - var item : js.html.DataTransferItem; - - public function new( item : js.html.DataTransferItem ) { - this.item = item; - if (item.kind == "file") { - var file = item.getAsFile(); - this.name = file.name; - this.type = file.type; - } else { - this.name = ""; - this.type = item.type; - } - } +private class NativeDroppedFile extends hxd.DropFileEvent.DroppedFile { public function getBytes( callback : ( data : haxe.io.Bytes ) -> Void ) { - if (item.kind == "file") { - var file = item.getAsFile(); - var reader = new js.html.FileReader(); - // TODO: Make sure no errors happen. - reader.onload = (_) -> callback(haxe.io.Bytes.ofData(reader.result)); - reader.readAsArrayBuffer(file); - } else { - item.getAsString(( str : String ) -> callback(haxe.io.Bytes.ofString(str)) ); - } - } - - public function getString( callback : ( data : String ) -> Void ) { - if (item.kind == "file") { - var file = item.getAsFile(); - var reader = new js.html.FileReader(); - // TODO: Make sure no errors happen. - reader.onload = (_) -> callback(reader.result); - reader.readAsText(file); - } else { - item.getAsString(( str : String ) -> callback(str) ); - } + var reader = new js.html.FileReader(); + reader.onload = (_) -> callback(haxe.io.Bytes.ofData(reader.result)); + reader.onerror = (_) -> callback(null); + reader.readAsArrayBuffer(native); } } @@ -61,7 +26,6 @@ class Window { var resizeEvents : List Void>; var eventTargets : List Void>; var dropTargets : List Void>; - var dropDragEvent: DropFileEvent = new DropFileEvent(DropMove, null); // Reused drag event when dragging over time. public var width(get, never) : Int; public var height(get, never) : Int; @@ -273,8 +237,6 @@ class Window { public function addDragAndDropTarget( f : ( event : DropFileEvent ) -> Void ) : Void { if( dropTargets.length == 0 ) { var element = canvas; // Probably should adhere to `globalEvents`? - element.addEventListener("dragenter", handleDragAndDropEvent); - element.addEventListener("dragleave", handleDragAndDropEvent); element.addEventListener("dragover", handleDragAndDropEvent); element.addEventListener("drop", handleDragAndDropEvent); } @@ -289,32 +251,21 @@ class Window { } if( dropTargets.length == 0 ) { var element = canvas; // Probably should adhere to `globalEvents`? - element.removeEventListener("dragenter", handleDragAndDropEvent); - element.removeEventListener("dragleave", handleDragAndDropEvent); element.removeEventListener("dragover", handleDragAndDropEvent); element.removeEventListener("drop", handleDragAndDropEvent); } } function handleDragAndDropEvent( e : js.html.DragEvent ) { - var files : Array = []; - // TODO: Don't allocate dropped file every time, only when it changes. - if( e.dataTransfer != null ) - for( i in 0...e.dataTransfer.items.length ) - files.push(new NativeDroppedFile(e.dataTransfer.items[i])); - var ev = switch( e.type ) { - case "dragenter": - new DropFileEvent(DropStart, files); - case "dragleave": - new DropFileEvent(DropEnd, files); - case "drop": - new DropFileEvent(Drop, files); - case "dragover": - dropDragEvent.files = files; - dropDragEvent; - default: throw "assert"; - } - for( e in dropTargets ) e(ev); + e.preventDefault(); + if ( e.type == "dragover" || e.dataTransfer == null || e.dataTransfer.files.length == 0 ) return; + var ev = new DropFileEvent([ + for ( file in e.dataTransfer.files ) new NativeDroppedFile(file) + ], + Math.round((e.clientX - canvasPos.left) * getPixelRatio()), + Math.round((e.clientY - canvasPos.top) * getPixelRatio()) + ); + for( dt in dropTargets ) dt(ev); } @:deprecated("Use the displayMode property instead") From b76a9dffea4563207e0250dff4a4342da1301449 Mon Sep 17 00:00:00 2001 From: Yanrishatum Date: Sun, 5 Nov 2023 17:11:49 +0300 Subject: [PATCH 4/4] Change DroppedFile.new --- hxd/DropFileEvent.hx | 8 ++------ hxd/Window.js.hx | 5 +++++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hxd/DropFileEvent.hx b/hxd/DropFileEvent.hx index 0a421a950..929115375 100644 --- a/hxd/DropFileEvent.hx +++ b/hxd/DropFileEvent.hx @@ -17,15 +17,11 @@ abstract class DroppedFile { **/ public var native(default, null) : js.html.File; - public function new( native : js.html.File ) { - this.file = native.name; - this.native = native; - } - #else + #end + public function new( file : String ) { this.file = file; } - #end /** diff --git a/hxd/Window.js.hx b/hxd/Window.js.hx index b9b81d9b8..22aa566ce 100644 --- a/hxd/Window.js.hx +++ b/hxd/Window.js.hx @@ -12,6 +12,11 @@ enum DisplayMode { private class NativeDroppedFile extends hxd.DropFileEvent.DroppedFile { + public function new( native : js.html.File ) { + super(native.name); + this.native = native; + } + public function getBytes( callback : ( data : haxe.io.Bytes ) -> Void ) { var reader = new js.html.FileReader(); reader.onload = (_) -> callback(haxe.io.Bytes.ofData(reader.result));