core: move input state tracking from Platform to Core
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
1c0434a948
commit
8447654311
4 changed files with 100 additions and 135 deletions
84
src/Core.zig
84
src/Core.zig
|
|
@ -156,6 +156,8 @@ descriptor: gpu.SwapChain.Descriptor,
|
||||||
|
|
||||||
// Internal state
|
// Internal state
|
||||||
events: EventQueue,
|
events: EventQueue,
|
||||||
|
input_state: InputState,
|
||||||
|
oom: std.Thread.ResetEvent = .{},
|
||||||
|
|
||||||
// TODO: this needs to be removed.
|
// TODO: this needs to be removed.
|
||||||
pub const InitOptions = struct {
|
pub const InitOptions = struct {
|
||||||
|
|
@ -208,6 +210,7 @@ fn init(core: *Mod, entities: *mach.Entities.Mod) !void {
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.main_window = main_window,
|
.main_window = main_window,
|
||||||
.events = events,
|
.events = events,
|
||||||
|
.input_state = .{},
|
||||||
|
|
||||||
// TODO: remove undefined initialization (disgusting!)
|
// TODO: remove undefined initialization (disgusting!)
|
||||||
.platform = undefined,
|
.platform = undefined,
|
||||||
|
|
@ -617,6 +620,41 @@ pub inline fn nextEvent(core: *@This()) ?Event {
|
||||||
return core.events.readItem();
|
return core.events.readItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Push an event onto the event queue, or set OOM if no space is available.
|
||||||
|
///
|
||||||
|
/// Updates the input_state tracker.
|
||||||
|
pub inline fn pushEvent(core: *@This(), event: Event) void {
|
||||||
|
// Write event
|
||||||
|
core.events.writeItem(event) catch {
|
||||||
|
core.oom.set();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update input state
|
||||||
|
switch (event) {
|
||||||
|
.key_press => |ev| core.input_state.keys.setValue(@intFromEnum(ev.key), true),
|
||||||
|
.key_release => |ev| core.input_state.keys.setValue(@intFromEnum(ev.key), false),
|
||||||
|
.mouse_press => |ev| core.input_state.mouse_buttons.setValue(@intFromEnum(ev.button), true),
|
||||||
|
.mouse_release => |ev| core.input_state.mouse_buttons.setValue(@intFromEnum(ev.button), false),
|
||||||
|
.mouse_motion => |ev| core.input_state.mouse_position = ev.pos,
|
||||||
|
.focus_lost => {
|
||||||
|
// Clear input state that may be 'stuck' when focus is regained.
|
||||||
|
core.input_state.keys = InputState.KeyBitSet.initEmpty();
|
||||||
|
core.input_state.mouse_buttons = InputState.MouseButtonSet.initEmpty();
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reports whether mach.Core ran out of memory, indicating events may have been dropped.
|
||||||
|
///
|
||||||
|
/// Once called, the OOM flag is reset and mach.Core will continue operating normally.
|
||||||
|
pub fn outOfMemory(core: *@This()) bool {
|
||||||
|
if (!core.oom.isSet()) return false;
|
||||||
|
core.oom.reset();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the window title. The string must be owned by Core, and will not be copied or freed. It is
|
/// Sets the window title. The string must be owned by Core, and will not be copied or freed. It is
|
||||||
/// advised to use the `core.title` buffer for this purpose, e.g.:
|
/// advised to use the `core.title` buffer for this purpose, e.g.:
|
||||||
///
|
///
|
||||||
|
|
@ -672,6 +710,26 @@ pub inline fn headless(core: *@This()) bool {
|
||||||
return core.platform.headless;
|
return core.platform.headless;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn keyPressed(core: *@This(), key: Key) bool {
|
||||||
|
return core.input_state.isKeyPressed(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn keyReleased(core: *@This(), key: Key) bool {
|
||||||
|
return core.input_state.isKeyReleased(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mousePressed(core: *@This(), button: MouseButton) bool {
|
||||||
|
return core.input_state.isMouseButtonPressed(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mouseReleased(core: *@This(), button: MouseButton) bool {
|
||||||
|
return core.input_state.isMouseButtonReleased(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mousePosition(core: *@This()) Position {
|
||||||
|
return core.input_state.mouse_position;
|
||||||
|
}
|
||||||
|
|
||||||
pub const VSyncMode = enum {
|
pub const VSyncMode = enum {
|
||||||
/// Potential screen tearing.
|
/// Potential screen tearing.
|
||||||
/// No synchronization with monitor, render frames as fast as possible.
|
/// No synchronization with monitor, render frames as fast as possible.
|
||||||
|
|
@ -784,31 +842,11 @@ pub inline fn cursorShape(core: *@This()) CursorShape {
|
||||||
return core.platform.cursorShape();
|
return core.platform.cursorShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn keyPressed(core: *@This(), key: Key) bool {
|
|
||||||
return core.platform.keyPressed(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn keyReleased(core: *@This(), key: Key) bool {
|
|
||||||
return core.platform.keyReleased(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn mousePressed(core: *@This(), button: MouseButton) bool {
|
|
||||||
return core.platform.mousePressed(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub inline fn mouseReleased(core: *@This(), button: MouseButton) bool {
|
|
||||||
return core.platform.mouseReleased(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Position = struct {
|
pub const Position = struct {
|
||||||
x: f64,
|
x: f64,
|
||||||
y: f64,
|
y: f64,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub inline fn mousePosition(core: *@This()) Position {
|
|
||||||
return core.platform.mousePosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the minimum target frequency of the input handling thread.
|
/// Sets the minimum target frequency of the input handling thread.
|
||||||
///
|
///
|
||||||
/// Input handling (the main thread) runs at a variable frequency. The thread blocks until there are
|
/// Input handling (the main thread) runs at a variable frequency. The thread blocks until there are
|
||||||
|
|
@ -1100,12 +1138,6 @@ comptime {
|
||||||
|
|
||||||
assertHasDecl(Platform, "setCursorShape");
|
assertHasDecl(Platform, "setCursorShape");
|
||||||
assertHasField(Platform, "cursor_shape");
|
assertHasField(Platform, "cursor_shape");
|
||||||
|
|
||||||
assertHasDecl(Platform, "keyPressed");
|
|
||||||
assertHasDecl(Platform, "keyReleased");
|
|
||||||
assertHasDecl(Platform, "mousePressed");
|
|
||||||
assertHasDecl(Platform, "mouseReleased");
|
|
||||||
assertHasDecl(Platform, "mousePosition");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assertHasDecl(comptime T: anytype, comptime decl_name: []const u8) void {
|
fn assertHasDecl(comptime T: anytype, comptime decl_name: []const u8) void {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ pub const Darwin = @This();
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
core: *Core,
|
core: *Core,
|
||||||
input_state: Core.InputState,
|
|
||||||
title: [:0]const u8,
|
title: [:0]const u8,
|
||||||
display_mode: DisplayMode,
|
display_mode: DisplayMode,
|
||||||
vsync_mode: VSyncMode,
|
vsync_mode: VSyncMode,
|
||||||
|
|
@ -109,7 +108,6 @@ pub fn init(
|
||||||
darwin.* = .{
|
darwin.* = .{
|
||||||
.allocator = options.allocator,
|
.allocator = options.allocator,
|
||||||
.core = @fieldParentPtr("platform", darwin),
|
.core = @fieldParentPtr("platform", darwin),
|
||||||
.input_state = .{},
|
|
||||||
.title = options.title,
|
.title = options.title,
|
||||||
.display_mode = options.display_mode,
|
.display_mode = options.display_mode,
|
||||||
.vsync_mode = .none,
|
.vsync_mode = .none,
|
||||||
|
|
@ -168,23 +166,3 @@ pub fn setCursorMode(_: *Darwin, _: CursorMode) void {
|
||||||
pub fn setCursorShape(_: *Darwin, _: CursorShape) void {
|
pub fn setCursorShape(_: *Darwin, _: CursorShape) void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keyPressed(_: *Darwin, _: Key) bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn keyReleased(_: *Darwin, _: Key) bool {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mousePressed(_: *Darwin, _: MouseButton) bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mouseReleased(_: *Darwin, _: MouseButton) bool {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mousePosition(_: *Darwin) Position {
|
|
||||||
return Position{ .x = 0, .y = 0 };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ pub const Null = @This();
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
core: *Core,
|
core: *Core,
|
||||||
input_state: Core.InputState,
|
|
||||||
modifiers: KeyMods,
|
modifiers: KeyMods,
|
||||||
title: [:0]u8,
|
title: [:0]u8,
|
||||||
display_mode: DisplayMode,
|
display_mode: DisplayMode,
|
||||||
|
|
@ -92,23 +91,3 @@ pub fn setCursorMode(_: *Null, _: CursorMode) void {
|
||||||
pub fn setCursorShape(_: *Null, _: CursorShape) void {
|
pub fn setCursorShape(_: *Null, _: CursorShape) void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keyPressed(_: *Null, _: Key) bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn keyReleased(_: *Null, _: Key) bool {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mousePressed(_: *Null, _: MouseButton) bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mouseReleased(_: *Null, _: MouseButton) bool {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mousePosition(_: *Null) Position {
|
|
||||||
return Position{ .x = 0, .y = 0 };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,6 @@ dinput: *w.IDirectInput8W,
|
||||||
saved_window_rect: w.RECT,
|
saved_window_rect: w.RECT,
|
||||||
surface_descriptor_from_hwnd: gpu.Surface.DescriptorFromWindowsHWND,
|
surface_descriptor_from_hwnd: gpu.Surface.DescriptorFromWindowsHWND,
|
||||||
state: *Core,
|
state: *Core,
|
||||||
input_state: Core.InputState,
|
|
||||||
oom: std.Thread.ResetEvent = .{},
|
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
// Platform interface
|
// Platform interface
|
||||||
|
|
@ -60,7 +58,6 @@ pub fn init(
|
||||||
self.allocator = options.allocator;
|
self.allocator = options.allocator;
|
||||||
self.core = @fieldParentPtr("platform", self);
|
self.core = @fieldParentPtr("platform", self);
|
||||||
self.size = options.size;
|
self.size = options.size;
|
||||||
self.input_state = .{};
|
|
||||||
self.saved_window_rect = .{ .top = 0, .left = 0, .right = 0, .bottom = 0 };
|
self.saved_window_rect = .{ .top = 0, .left = 0, .right = 0, .bottom = 0 };
|
||||||
|
|
||||||
const hInstance = w.GetModuleHandleW(null);
|
const hInstance = w.GetModuleHandleW(null);
|
||||||
|
|
@ -153,7 +150,7 @@ pub fn update(self: *Win32) !void {
|
||||||
|
|
||||||
pub fn setTitle(self: *Win32, title: [:0]const u8) void {
|
pub fn setTitle(self: *Win32, title: [:0]const u8) void {
|
||||||
const wtitle = std.unicode.utf8ToUtf16LeAllocZ(self.allocator, title) catch {
|
const wtitle = std.unicode.utf8ToUtf16LeAllocZ(self.allocator, title) catch {
|
||||||
self.oom.set();
|
self.state.oom.set();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
defer self.allocator.free(wtitle);
|
defer self.allocator.free(wtitle);
|
||||||
|
|
@ -258,26 +255,6 @@ pub fn setCursorShape(self: *Win32, shape: CursorShape) void {
|
||||||
self.cursor_shape = shape;
|
self.cursor_shape = shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keyPressed(self: *Win32, key: Key) bool {
|
|
||||||
return self.input_state.isKeyPressed(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn keyReleased(self: *Win32, key: Key) bool {
|
|
||||||
return self.input_state.isKeyReleased(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mousePressed(self: *Win32, button: MouseButton) bool {
|
|
||||||
return self.input_state.isMouseButtonPressed(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mouseReleased(self: *Win32, button: MouseButton) bool {
|
|
||||||
return self.input_state.isMouseButtonReleased(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mousePosition(self: *Win32) Position {
|
|
||||||
return self.input_state.mouse_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nativeWindowWin32(self: *Win32) w.HWND {
|
pub fn nativeWindowWin32(self: *Win32) w.HWND {
|
||||||
return self.window;
|
return self.window;
|
||||||
}
|
}
|
||||||
|
|
@ -303,18 +280,6 @@ fn restoreWindowPosition(self: *Win32) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outOfMemory(self: *Win32) bool {
|
|
||||||
if (self.oom.isSet()) {
|
|
||||||
self.oom.reset();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pushEvent(self: *Win32, event: Event) void {
|
|
||||||
self.state.events.writeItem(event) catch self.oom.set();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn getKeyboardModifiers() mach.Core.KeyMods {
|
fn getKeyboardModifiers() mach.Core.KeyMods {
|
||||||
return .{
|
return .{
|
||||||
.shift = w.GetKeyState(@as(i32, @intFromEnum(w.VK_SHIFT))) < 0, //& 0x8000 == 0x8000,
|
.shift = w.GetKeyState(@as(i32, @intFromEnum(w.VK_SHIFT))) < 0, //& 0x8000 == 0x8000,
|
||||||
|
|
@ -336,7 +301,7 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
|
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
w.WM_CLOSE => {
|
w.WM_CLOSE => {
|
||||||
self.pushEvent(.close);
|
self.state.pushEvent(.close);
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
w.WM_SIZE => {
|
w.WM_SIZE => {
|
||||||
|
|
@ -358,7 +323,7 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
if (vkey == w.VK_PROCESSKEY) return 0;
|
if (vkey == w.VK_PROCESSKEY) return 0;
|
||||||
|
|
||||||
if (msg == w.WM_SYSKEYDOWN and vkey == w.VK_F4) {
|
if (msg == w.WM_SYSKEYDOWN and vkey == w.VK_F4) {
|
||||||
self.pushEvent(.close);
|
self.state.pushEvent(.close);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -381,16 +346,26 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
const mods = getKeyboardModifiers();
|
const mods = getKeyboardModifiers();
|
||||||
const key = keyFromScancode(scancode);
|
const key = keyFromScancode(scancode);
|
||||||
if (msg == w.WM_KEYDOWN or msg == w.WM_SYSKEYDOWN) {
|
if (msg == w.WM_KEYDOWN or msg == w.WM_SYSKEYDOWN) {
|
||||||
if (flags & w.KF_REPEAT == 0) {
|
if (flags & w.KF_REPEAT == 0)
|
||||||
self.pushEvent(.{ .key_press = .{ .key = key, .mods = mods } });
|
self.state.pushEvent(.{
|
||||||
self.input_state.keys.setValue(@intFromEnum(key), true);
|
.key_press = .{
|
||||||
} else {
|
.key = key,
|
||||||
self.pushEvent(.{ .key_repeat = .{ .key = key, .mods = mods } });
|
.mods = mods,
|
||||||
}
|
},
|
||||||
} else {
|
})
|
||||||
self.pushEvent(.{ .key_release = .{ .key = key, .mods = mods } });
|
else
|
||||||
self.input_state.keys.setValue(@intFromEnum(key), false);
|
self.state.pushEvent(.{
|
||||||
}
|
.key_repeat = .{
|
||||||
|
.key = key,
|
||||||
|
.mods = mods,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else self.state.pushEvent(.{
|
||||||
|
.key_release = .{
|
||||||
|
.key = key,
|
||||||
|
.mods = mods,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
|
@ -408,7 +383,7 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
}
|
}
|
||||||
var iter = std.unicode.Utf16LeIterator.init(chars);
|
var iter = std.unicode.Utf16LeIterator.init(chars);
|
||||||
if (iter.nextCodepoint()) |codepoint| {
|
if (iter.nextCodepoint()) |codepoint| {
|
||||||
self.pushEvent(.{ .char_input = .{ .codepoint = codepoint.? } });
|
self.state.pushEvent(.{ .char_input = .{ .codepoint = codepoint.? } });
|
||||||
} else |err| {
|
} else |err| {
|
||||||
err catch {};
|
err catch {};
|
||||||
}
|
}
|
||||||
|
|
@ -439,14 +414,20 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
w.WM_MBUTTONDOWN,
|
w.WM_MBUTTONDOWN,
|
||||||
w.WM_RBUTTONDOWN,
|
w.WM_RBUTTONDOWN,
|
||||||
w.WM_XBUTTONDOWN,
|
w.WM_XBUTTONDOWN,
|
||||||
=> {
|
=> self.state.pushEvent(.{
|
||||||
self.pushEvent(.{ .mouse_press = .{ .button = button, .mods = mods, .pos = .{ .x = x, .y = y } } });
|
.mouse_press = .{
|
||||||
self.input_state.mouse_buttons.setValue(@intFromEnum(button), true);
|
.button = button,
|
||||||
|
.mods = mods,
|
||||||
|
.pos = .{ .x = x, .y = y },
|
||||||
},
|
},
|
||||||
else => {
|
}),
|
||||||
self.pushEvent(.{ .mouse_release = .{ .button = button, .mods = mods, .pos = .{ .x = x, .y = y } } });
|
else => self.state.pushEvent(.{
|
||||||
self.input_state.mouse_buttons.setValue(@intFromEnum(button), false);
|
.mouse_release = .{
|
||||||
|
.button = button,
|
||||||
|
.mods = mods,
|
||||||
|
.pos = .{ .x = x, .y = y },
|
||||||
},
|
},
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (msg == w.WM_XBUTTONDOWN or msg == w.WM_XBUTTONUP) w.TRUE else 0;
|
return if (msg == w.WM_XBUTTONDOWN or msg == w.WM_XBUTTONUP) w.TRUE else 0;
|
||||||
|
|
@ -454,8 +435,7 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
w.WM_MOUSEMOVE => {
|
w.WM_MOUSEMOVE => {
|
||||||
const x: f64 = @floatFromInt(@as(i16, @truncate(lParam & 0xFFFF)));
|
const x: f64 = @floatFromInt(@as(i16, @truncate(lParam & 0xFFFF)));
|
||||||
const y: f64 = @floatFromInt(@as(i16, @truncate((lParam >> 16) & 0xFFFF)));
|
const y: f64 = @floatFromInt(@as(i16, @truncate((lParam >> 16) & 0xFFFF)));
|
||||||
|
self.state.pushEvent(.{
|
||||||
self.pushEvent(.{
|
|
||||||
.mouse_motion = .{
|
.mouse_motion = .{
|
||||||
.pos = .{
|
.pos = .{
|
||||||
.x = x,
|
.x = x,
|
||||||
|
|
@ -463,8 +443,6 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
self.input_state.mouse_position = .{ .x = x, .y = y };
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
w.WM_MOUSEWHEEL => {
|
w.WM_MOUSEWHEEL => {
|
||||||
|
|
@ -472,7 +450,7 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
const wheel_high_word: u16 = @truncate((wParam >> 16) & 0xffff);
|
const wheel_high_word: u16 = @truncate((wParam >> 16) & 0xffff);
|
||||||
const delta_y: f32 = @as(f32, @floatFromInt(@as(i16, @bitCast(wheel_high_word)))) / WHEEL_DELTA;
|
const delta_y: f32 = @as(f32, @floatFromInt(@as(i16, @bitCast(wheel_high_word)))) / WHEEL_DELTA;
|
||||||
|
|
||||||
self.pushEvent(.{
|
self.state.pushEvent(.{
|
||||||
.mouse_scroll = .{
|
.mouse_scroll = .{
|
||||||
.xoffset = 0,
|
.xoffset = 0,
|
||||||
.yoffset = delta_y,
|
.yoffset = delta_y,
|
||||||
|
|
@ -481,13 +459,11 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
w.WM_SETFOCUS => {
|
w.WM_SETFOCUS => {
|
||||||
self.pushEvent(.{ .focus_gained = {} });
|
self.state.pushEvent(.{ .focus_gained = {} });
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
w.WM_KILLFOCUS => {
|
w.WM_KILLFOCUS => {
|
||||||
self.pushEvent(.{ .focus_lost = {} });
|
self.state.pushEvent(.{ .focus_lost = {} });
|
||||||
// Clear input state when focus is lost to avoid "stuck" button when focus is regained.
|
|
||||||
self.input_state = .{};
|
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
else => return w.DefWindowProcW(wnd, msg, wParam, lParam),
|
else => return w.DefWindowProcW(wnd, msg, wParam, lParam),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue