parent
da046f340d
commit
5bb740f89e
4 changed files with 218 additions and 66 deletions
|
|
@ -196,29 +196,41 @@ const mach = {
|
||||||
canvas.addEventListener("contextmenu", (ev) => ev.preventDefault());
|
canvas.addEventListener("contextmenu", (ev) => ev.preventDefault());
|
||||||
|
|
||||||
canvas.addEventListener("keydown", (ev) => {
|
canvas.addEventListener("keydown", (ev) => {
|
||||||
mach.events.push(...[1, convertKeyCode(ev.code)]);
|
if (ev.repeat) {
|
||||||
|
mach.events.push(...[2, convertKeyCode(ev.code)]);
|
||||||
|
} else {
|
||||||
|
mach.events.push(...[1, convertKeyCode(ev.code)]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener("keyup", (ev) => {
|
canvas.addEventListener("keyup", (ev) => {
|
||||||
mach.events.push(...[2, convertKeyCode(ev.code)]);
|
mach.events.push(...[3, convertKeyCode(ev.code)]);
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener("mousemove", (ev) => {
|
canvas.addEventListener("mousemove", (ev) => {
|
||||||
mach.events.push(...[3, ev.clientX, ev.clientY]);
|
mach.events.push(...[4, ev.clientX, ev.clientY]);
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener("mousedown", (ev) => {
|
canvas.addEventListener("mousedown", (ev) => {
|
||||||
mach.events.push(...[4, ev.button]);
|
|
||||||
});
|
|
||||||
|
|
||||||
canvas.addEventListener("mouseup", (ev) => {
|
|
||||||
mach.events.push(...[5, ev.button]);
|
mach.events.push(...[5, ev.button]);
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener("wheel", (ev) => {
|
canvas.addEventListener("mouseup", (ev) => {
|
||||||
mach.events.push(...[6, ev.deltaX, ev.deltaY]);
|
mach.events.push(...[6, ev.button]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener("wheel", (ev) => {
|
||||||
|
mach.events.push(...[7, ev.deltaX, ev.deltaY]);
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener("focus", (ev) => {
|
||||||
|
mach.events.push(...[8]);
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener("blur", (ev) => {
|
||||||
|
mach.events.push(...[9]);
|
||||||
|
});
|
||||||
|
|
||||||
canvas.addEventListener("mach-canvas-resize", (ev) => {
|
canvas.addEventListener("mach-canvas-resize", (ev) => {
|
||||||
const cv_index = mach.canvases.findIndex((el) => el.canvas === ev.currentTarget);
|
const cv_index = mach.canvases.findIndex((el) => el.canvas === ev.currentTarget);
|
||||||
const cv = mach.canvases[cv_index];
|
const cv = mach.canvases[cv_index];
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ pub const Platform = struct {
|
||||||
|
|
||||||
native_instance: gpu.NativeInstance,
|
native_instance: gpu.NativeInstance,
|
||||||
|
|
||||||
|
last_cursor_position: structs.WindowPos,
|
||||||
|
|
||||||
const EventQueue = std.TailQueue(structs.Event);
|
const EventQueue = std.TailQueue(structs.Event);
|
||||||
const EventNode = EventQueue.Node;
|
const EventNode = EventQueue.Node;
|
||||||
|
|
||||||
|
|
@ -180,6 +182,8 @@ pub const Platform = struct {
|
||||||
engine.current_desc = descriptor;
|
engine.current_desc = descriptor;
|
||||||
engine.target_desc = descriptor;
|
engine.target_desc = descriptor;
|
||||||
|
|
||||||
|
const cursor_pos = try window.getCursorPos();
|
||||||
|
|
||||||
return Platform{
|
return Platform{
|
||||||
.window = window,
|
.window = window,
|
||||||
.backend_type = backend_type,
|
.backend_type = backend_type,
|
||||||
|
|
@ -187,6 +191,10 @@ pub const Platform = struct {
|
||||||
.last_window_size = .{ .width = window_size.width, .height = window_size.height },
|
.last_window_size = .{ .width = window_size.width, .height = window_size.height },
|
||||||
.last_framebuffer_size = .{ .width = framebuffer_size.width, .height = framebuffer_size.height },
|
.last_framebuffer_size = .{ .width = framebuffer_size.width, .height = framebuffer_size.height },
|
||||||
.last_position = try window.getPos(),
|
.last_position = try window.getPos(),
|
||||||
|
.last_cursor_position = .{
|
||||||
|
.x = cursor_pos.xpos,
|
||||||
|
.y = cursor_pos.ypos,
|
||||||
|
},
|
||||||
.native_instance = native_instance,
|
.native_instance = native_instance,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -210,37 +218,48 @@ pub const Platform = struct {
|
||||||
|
|
||||||
platform.window.setUserPointer(&platform.user_ptr);
|
platform.window.setUserPointer(&platform.user_ptr);
|
||||||
|
|
||||||
const callback = struct {
|
const key_callback = struct {
|
||||||
fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void {
|
fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void {
|
||||||
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
||||||
|
const key_event = structs.KeyEvent{
|
||||||
|
.key = toMachKey(key),
|
||||||
|
.mods = toMachMods(mods),
|
||||||
|
};
|
||||||
switch (action) {
|
switch (action) {
|
||||||
.press => pf.pushEvent(.{
|
.press => pf.pushEvent(.{ .key_press = key_event }),
|
||||||
.key_press = .{
|
.repeat => pf.pushEvent(.{ .key_repeat = key_event }),
|
||||||
.key = toMachKey(key),
|
.release => pf.pushEvent(.{ .key_release = key_event }),
|
||||||
},
|
|
||||||
}),
|
|
||||||
.release => pf.pushEvent(.{
|
|
||||||
.key_release = .{
|
|
||||||
.key = toMachKey(key),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
else => {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = scancode;
|
_ = scancode;
|
||||||
_ = mods;
|
|
||||||
}
|
}
|
||||||
}.callback;
|
}.callback;
|
||||||
platform.window.setKeyCallback(callback);
|
platform.window.setKeyCallback(key_callback);
|
||||||
|
|
||||||
|
const char_callback = struct {
|
||||||
|
fn callback(window: glfw.Window, codepoint: u21) void {
|
||||||
|
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
||||||
|
pf.pushEvent(.{
|
||||||
|
.char_input = .{
|
||||||
|
.codepoint = codepoint,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}.callback;
|
||||||
|
platform.window.setCharCallback(char_callback);
|
||||||
|
|
||||||
const mouse_motion_callback = struct {
|
const mouse_motion_callback = struct {
|
||||||
fn callback(window: glfw.Window, xpos: f64, ypos: f64) void {
|
fn callback(window: glfw.Window, xpos: f64, ypos: f64) void {
|
||||||
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
||||||
|
pf.last_cursor_position = .{
|
||||||
|
.x = xpos,
|
||||||
|
.y = ypos,
|
||||||
|
};
|
||||||
pf.pushEvent(.{
|
pf.pushEvent(.{
|
||||||
.mouse_motion = .{
|
.mouse_motion = .{
|
||||||
.x = xpos,
|
.pos = .{
|
||||||
.y = ypos,
|
.x = xpos,
|
||||||
|
.y = ypos,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -250,17 +269,15 @@ pub const Platform = struct {
|
||||||
const mouse_button_callback = struct {
|
const mouse_button_callback = struct {
|
||||||
fn callback(window: glfw.Window, button: glfw.mouse_button.MouseButton, action: glfw.Action, mods: glfw.Mods) void {
|
fn callback(window: glfw.Window, button: glfw.mouse_button.MouseButton, action: glfw.Action, mods: glfw.Mods) void {
|
||||||
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
||||||
|
const mouse_button_event = structs.MouseButtonEvent{
|
||||||
|
.button = toMachButton(button),
|
||||||
|
.pos = pf.last_cursor_position,
|
||||||
|
.mods = toMachMods(mods),
|
||||||
|
};
|
||||||
switch (action) {
|
switch (action) {
|
||||||
.press => pf.pushEvent(.{
|
.press => pf.pushEvent(.{ .mouse_press = mouse_button_event }),
|
||||||
.mouse_press = .{
|
|
||||||
.button = toMachButton(button),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
.release => pf.pushEvent(.{
|
.release => pf.pushEvent(.{
|
||||||
.mouse_release = .{
|
.mouse_release = mouse_button_event,
|
||||||
.button = toMachButton(button),
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
@ -283,6 +300,22 @@ pub const Platform = struct {
|
||||||
}.callback;
|
}.callback;
|
||||||
platform.window.setScrollCallback(scroll_callback);
|
platform.window.setScrollCallback(scroll_callback);
|
||||||
|
|
||||||
|
const focus_callback = struct {
|
||||||
|
fn callback(window: glfw.Window, focused: bool) void {
|
||||||
|
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
||||||
|
pf.pushEvent(if (focused) .focus_gained else .focus_lost);
|
||||||
|
}
|
||||||
|
}.callback;
|
||||||
|
platform.window.setFocusCallback(focus_callback);
|
||||||
|
|
||||||
|
const close_callback = struct {
|
||||||
|
fn callback(window: glfw.Window) void {
|
||||||
|
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
||||||
|
pf.pushEvent(.closed);
|
||||||
|
}
|
||||||
|
}.callback;
|
||||||
|
platform.window.setCloseCallback(close_callback);
|
||||||
|
|
||||||
const size_callback = struct {
|
const size_callback = struct {
|
||||||
fn callback(window: glfw.Window, width: i32, height: i32) void {
|
fn callback(window: glfw.Window, width: i32, height: i32) void {
|
||||||
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
const pf = (window.getUserPointer(UserPtr) orelse unreachable).platform;
|
||||||
|
|
@ -526,6 +559,17 @@ pub const Platform = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn toMachMods(mods: glfw.Mods) structs.KeyMods {
|
||||||
|
return .{
|
||||||
|
.shift = mods.shift,
|
||||||
|
.control = mods.control,
|
||||||
|
.alt = mods.alt,
|
||||||
|
.super = mods.super,
|
||||||
|
.caps_lock = mods.caps_lock,
|
||||||
|
.num_lock = mods.num_lock,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Default GLFW error handling callback
|
/// Default GLFW error handling callback
|
||||||
fn errorCallback(error_code: glfw.Error, description: [:0]const u8) void {
|
fn errorCallback(error_code: glfw.Error, description: [:0]const u8) void {
|
||||||
std.debug.print("glfw: {}: {s}\n", .{ error_code, description });
|
std.debug.print("glfw: {}: {s}\n", .{ error_code, description });
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,9 @@ pub const Platform = struct {
|
||||||
last_window_size: structs.Size,
|
last_window_size: structs.Size,
|
||||||
last_framebuffer_size: structs.Size,
|
last_framebuffer_size: structs.Size,
|
||||||
|
|
||||||
|
last_cursor_position: structs.WindowPos,
|
||||||
|
last_key_mods: structs.KeyMods,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, eng: *Engine) !Platform {
|
pub fn init(allocator: std.mem.Allocator, eng: *Engine) !Platform {
|
||||||
var selector = [1]u8{0} ** 15;
|
var selector = [1]u8{0} ** 15;
|
||||||
const id = js.machCanvasInit(&selector[0]);
|
const id = js.machCanvasInit(&selector[0]);
|
||||||
|
|
@ -53,6 +56,20 @@ pub const Platform = struct {
|
||||||
.width = js.machCanvasGetFramebufferWidth(id),
|
.width = js.machCanvasGetFramebufferWidth(id),
|
||||||
.height = js.machCanvasGetFramebufferHeight(id),
|
.height = js.machCanvasGetFramebufferHeight(id),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO initialize these properly
|
||||||
|
.last_cursor_position = .{
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
},
|
||||||
|
.last_key_mods = .{
|
||||||
|
.shift = false,
|
||||||
|
.control = false,
|
||||||
|
.alt = false,
|
||||||
|
.super = false,
|
||||||
|
.caps_lock = false,
|
||||||
|
.num_lock = false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
try platform.setOptions(eng.options);
|
try platform.setOptions(eng.options);
|
||||||
|
|
@ -117,38 +134,93 @@ pub const Platform = struct {
|
||||||
return js.machHasEvent();
|
return js.machHasEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pollEvent(_: *Platform) ?structs.Event {
|
pub fn pollEvent(platform: *Platform) ?structs.Event {
|
||||||
const event_type = js.machEventShift();
|
const event_type = js.machEventShift();
|
||||||
|
|
||||||
return switch (event_type) {
|
return switch (event_type) {
|
||||||
1 => structs.Event{
|
1, 2 => key_down: {
|
||||||
.key_press = .{ .key = @intToEnum(enums.Key, js.machEventShift()) },
|
const key = @intToEnum(enums.Key, js.machEventShift());
|
||||||
|
switch (key) {
|
||||||
|
.left_shift, .right_shift => platform.last_key_mods.shift = true,
|
||||||
|
.left_control, .right_control => platform.last_key_mods.control = true,
|
||||||
|
.left_alt, .right_alt => platform.last_key_mods.alt = true,
|
||||||
|
.left_super, .right_super => platform.last_key_mods.super = true,
|
||||||
|
.caps_lock => platform.last_key_mods.caps_lock = true,
|
||||||
|
.num_lock => platform.last_key_mods.num_lock = true,
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
break :key_down switch (event_type) {
|
||||||
|
1 => structs.Event{
|
||||||
|
.key_press = .{
|
||||||
|
.key = key,
|
||||||
|
.mods = platform.last_key_mods,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
2 => structs.Event{
|
||||||
|
.key_repeat = .{
|
||||||
|
.key = key,
|
||||||
|
.mods = platform.last_key_mods,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
2 => structs.Event{
|
3 => key_release: {
|
||||||
.key_release = .{ .key = @intToEnum(enums.Key, js.machEventShift()) },
|
const key = @intToEnum(enums.Key, js.machEventShift());
|
||||||
|
switch (key) {
|
||||||
|
.left_shift, .right_shift => platform.last_key_mods.shift = false,
|
||||||
|
.left_control, .right_control => platform.last_key_mods.control = false,
|
||||||
|
.left_alt, .right_alt => platform.last_key_mods.alt = false,
|
||||||
|
.left_super, .right_super => platform.last_key_mods.super = false,
|
||||||
|
.caps_lock => platform.last_key_mods.caps_lock = false,
|
||||||
|
.num_lock => platform.last_key_mods.num_lock = false,
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
break :key_release structs.Event{
|
||||||
|
.key_release = .{
|
||||||
|
.key = key,
|
||||||
|
.mods = platform.last_key_mods,
|
||||||
|
},
|
||||||
|
};
|
||||||
},
|
},
|
||||||
3 => structs.Event{
|
4 => mouse_motion: {
|
||||||
.mouse_motion = .{
|
const x = @intToFloat(f64, js.machEventShift());
|
||||||
.x = @intToFloat(f64, js.machEventShift()),
|
const y = @intToFloat(f64, js.machEventShift());
|
||||||
.y = @intToFloat(f64, js.machEventShift()),
|
platform.last_cursor_position = .{
|
||||||
},
|
.x = x,
|
||||||
},
|
.y = y,
|
||||||
4 => structs.Event{
|
};
|
||||||
.mouse_press = .{
|
break :mouse_motion structs.Event{
|
||||||
.button = toMachButton(js.machEventShift()),
|
.mouse_motion = .{
|
||||||
},
|
.pos = .{
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
},
|
},
|
||||||
5 => structs.Event{
|
5 => structs.Event{
|
||||||
.mouse_release = .{
|
.mouse_press = .{
|
||||||
.button = toMachButton(js.machEventShift()),
|
.button = toMachButton(js.machEventShift()),
|
||||||
|
.pos = platform.last_cursor_position,
|
||||||
|
.mods = platform.last_key_mods,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
6 => structs.Event{
|
6 => structs.Event{
|
||||||
|
.mouse_release = .{
|
||||||
|
.button = toMachButton(js.machEventShift()),
|
||||||
|
.pos = platform.last_cursor_position,
|
||||||
|
.mods = platform.last_key_mods,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
7 => structs.Event{
|
||||||
.mouse_scroll = .{
|
.mouse_scroll = .{
|
||||||
.xoffset = @floatCast(f32, sign(js.machEventShiftFloat())),
|
.xoffset = @floatCast(f32, sign(js.machEventShiftFloat())),
|
||||||
.yoffset = @floatCast(f32, sign(js.machEventShiftFloat())),
|
.yoffset = @floatCast(f32, sign(js.machEventShiftFloat())),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
8 => structs.Event.focus_gained,
|
||||||
|
9 => structs.Event.focus_lost,
|
||||||
else => null,
|
else => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,25 +48,49 @@ pub const Options = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Event = union(enum) {
|
pub const Event = union(enum) {
|
||||||
key_press: struct {
|
key_press: KeyEvent,
|
||||||
key: enums.Key,
|
key_repeat: KeyEvent,
|
||||||
},
|
key_release: KeyEvent,
|
||||||
key_release: struct {
|
char_input: struct {
|
||||||
key: enums.Key,
|
codepoint: u21,
|
||||||
},
|
},
|
||||||
mouse_motion: struct {
|
mouse_motion: struct {
|
||||||
// These are in window coordinates (not framebuffer coords)
|
pos: WindowPos,
|
||||||
x: f64,
|
|
||||||
y: f64,
|
|
||||||
},
|
|
||||||
mouse_press: struct {
|
|
||||||
button: enums.MouseButton,
|
|
||||||
},
|
|
||||||
mouse_release: struct {
|
|
||||||
button: enums.MouseButton,
|
|
||||||
},
|
},
|
||||||
|
mouse_press: MouseButtonEvent,
|
||||||
|
mouse_release: MouseButtonEvent,
|
||||||
mouse_scroll: struct {
|
mouse_scroll: struct {
|
||||||
xoffset: f32,
|
xoffset: f32,
|
||||||
yoffset: f32,
|
yoffset: f32,
|
||||||
},
|
},
|
||||||
|
focus_gained,
|
||||||
|
focus_lost,
|
||||||
|
closed,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const KeyEvent = struct {
|
||||||
|
key: enums.Key,
|
||||||
|
mods: KeyMods,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MouseButtonEvent = struct {
|
||||||
|
button: enums.MouseButton,
|
||||||
|
pos: WindowPos,
|
||||||
|
mods: KeyMods,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const KeyMods = packed struct {
|
||||||
|
shift: bool,
|
||||||
|
control: bool,
|
||||||
|
alt: bool,
|
||||||
|
super: bool,
|
||||||
|
caps_lock: bool,
|
||||||
|
num_lock: bool,
|
||||||
|
_reserved: u2 = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const WindowPos = struct {
|
||||||
|
// These are in window coordinates (not framebuffer coords)
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue