Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hldx] Implement Drag&Drop api #630

Merged
merged 3 commits into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libs/directx/dx/Event.hx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ package dx;
public var keyRepeat : Bool;
public var controller : Int;
public var value : Int;
public var dropFile: hl.Bytes;
public function new() {
}
}
Expand All @@ -29,6 +30,9 @@ enum abstract EventType(Int) {
var KeyDown = 7;
var KeyUp = 8;
var TextInput = 9;
var DropStart = 10;
var DropFile = 11;
var DropEnd = 12;
}

enum abstract WindowStateChange(Int) {
Expand Down
10 changes: 10 additions & 0 deletions libs/directx/dx/Window.hx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Window {
public var displaySetting : DisplaySetting;
public var selectedMonitor : MonitorHandle;
public var vsync : Bool;
public var dragAndDropEnabled(default, set) : Bool;

public function new( title : String, width : Int, height : Int, x : Int = CW_USEDEFAULT, y : Int = CW_USEDEFAULT, windowFlags : Int = RESIZABLE ) {
win = winCreateEx(x, y, width, height, windowFlags);
Expand Down Expand Up @@ -243,6 +244,11 @@ class Window {
winSetOpacity(win, v);
return v;
}

function set_dragAndDropEnabled(v) {
winSetDragAcceptFiles(win, v);
return dragAndDropEnabled = v;
}

@:hlNative("?directx", "win_get_display_settings")
static function winGetDisplaySettings(monitor : hl.Bytes) : hl.NativeArray<Dynamic> {
Expand Down Expand Up @@ -354,5 +360,9 @@ class Window {
static function winGetRelativeMouseMode() : Bool {
return false;
}

@:hlNative("?directx", "win_set_drag_accept_files")
static function winSetDragAcceptFiles( win : WinPtr, enable: Bool ) : Void {
}

}
2 changes: 1 addition & 1 deletion libs/directx/haxelib.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license" : "BSD",
"contributors" : ["ncannasse"],
"description" : "DirectX support for Haxe/HL.",
"version" : "1.13.0",
"version" : "1.14.0",
"releasenote" : "",
"dependencies": { "hlopenal" : "" }
}
64 changes: 63 additions & 1 deletion libs/directx/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ typedef enum {
WindowState = 6,
KeyDown = 7,
KeyUp = 8,
TextInput = 9
TextInput = 9,
DropStart = 10,
DropFile = 11,
DropEnd = 12,
} EventType;

typedef enum {
Expand Down Expand Up @@ -52,6 +55,7 @@ typedef struct {
bool keyRepeat;
int controller;
int value;
vbyte* dropFile;
} dx_event;

typedef struct {
Expand Down Expand Up @@ -459,6 +463,47 @@ static LRESULT CALLBACK WndProc( HWND wnd, UINT umsg, WPARAM wparam, LPARAM lpar
return TRUE;
}
break;
case WM_DROPFILES:
{
HDROP drop = (HDROP)wparam;
UINT count = DragQueryFileW(drop, 0xFFFFFFFF, NULL, 0);

POINT dragPoint;
if ( !DragQueryPoint(drop, &dragPoint) ) {
dragPoint.x = 0L;
dragPoint.y = 0L;
}

e = addEvent(wnd, DropStart);
e->value = count;
e->mouseX = (int)dragPoint.x;
e->mouseY = (int)dragPoint.y;

for ( UINT i = 0; i < count; i++ ) {
UINT size = DragQueryFileW(drop, i, NULL, 0) + 1; // + zero terminator
// We have to make a temporary unmanaged buffer copy due to async nature of event being
// processed and collected by Haxe event loop, and using GC-allocated buffer risks
// resulting in garbage data if GC is ran at any point inbetween due to freed buffer.
// As a consequence, this event requires checks during fetching of the next event
// (and window destruction) in order to ensure Haxe side gets proper buffer without memory leaks.
vbyte* buffer = malloc(size * sizeof(WCHAR));
if ( DragQueryFileW(drop, i, (LPWSTR)buffer, size) ) {
e = addEvent(wnd, DropFile);
e->value = size * sizeof(WCHAR);
e->dropFile = buffer;
e->mouseX = (int)dragPoint.x;
e->mouseY = (int)dragPoint.y;
} else {
free(buffer);
}
}
e = addEvent(wnd, DropEnd);
e->value = count;
e->mouseX = (int)dragPoint.x;
e->mouseY = (int)dragPoint.y;
DragFinish(drop);
break;
}
case WM_CLOSE:
addEvent(wnd, Quit);
return 0;
Expand Down Expand Up @@ -704,6 +749,11 @@ HL_PRIM void HL_NAME(win_destroy)(dx_window *win) {
ClipCursor(NULL);
}
dx_events *buf = get_events(win);
// See WM_DROPFILES comment regarding GC
for ( int i = buf->next_event; i < buf->event_count; i++ ) {
if ( buf->events[i].dropFile != NULL )
free(buf->events[i].dropFile);
}
free(buf);
SetWindowLongPtr(win,GWLP_USERDATA,0);
DestroyWindow(win);
Expand All @@ -722,6 +772,13 @@ HL_PRIM bool HL_NAME(win_get_next_event)( dx_window *win, dx_event *e ) {
}
save = e->t;
memcpy(e,&buf->events[buf->next_event++],sizeof(dx_event));
if ( e->type == DropFile ) {
// See WM_DROPFILES comment regarding GC
vbyte* unmanaged = e->dropFile;
e->dropFile = hl_copy_bytes(unmanaged, e->value);
free(unmanaged);
buf->events[buf->next_event - 1].dropFile = NULL;
}
e->t = save;
return true;
}
Expand Down Expand Up @@ -754,6 +811,10 @@ HL_PRIM bool HL_NAME(win_get_relative_mouse_mode)() {
return relative_mouse;
}

HL_PRIM void HL_NAME(win_set_drag_accept_files)( dx_window* wnd, bool enabled ) {
DragAcceptFiles(wnd, enabled);
}

HL_PRIM int HL_NAME(get_screen_width)() {
return GetSystemMetrics(SM_CXSCREEN);
}
Expand Down Expand Up @@ -875,6 +936,7 @@ DEFINE_PRIM(_BOOL, set_cursor_pos, _I32 _I32);
DEFINE_PRIM(_BOOL, win_set_cursor_pos, TWIN _I32 _I32);
DEFINE_PRIM(_BOOL, win_set_relative_mouse_mode, TWIN _BOOL);
DEFINE_PRIM(_BOOL, win_get_relative_mouse_mode, _NO_ARG);
DEFINE_PRIM(_VOID, win_set_drag_accept_files, TWIN _BOOL);
DEFINE_PRIM(_ARR, win_get_display_settings, _BYTES);
DEFINE_PRIM(_DYN, win_get_current_display_setting, _BYTES _BOOL);
DEFINE_PRIM(_I32, win_change_display_setting, _BYTES _DYN);
Expand Down
2 changes: 1 addition & 1 deletion libs/sdl/haxelib.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license" : "BSD",
"contributors" : ["ncannasse"],
"description" : "SDL/GL support for Haxe/HL.",
"version" : "1.13.0",
"version" : "1.14.0",
"releasenote" : "",
"dependencies": { "hlopenal" : "" }
}