mach: mouse cursor support (#352)
adds mouse cursor support for standard cursors Co-authored-by: Stephen Gutekanst <stephen.gutekanst@gmail.com>
This commit is contained in:
parent
f5affbe7ae
commit
43bff35d2c
5 changed files with 87 additions and 0 deletions
|
|
@ -87,6 +87,10 @@ pub fn getWindowSize(engine: *Engine) structs.Size {
|
||||||
return engine.internal.getWindowSize();
|
return engine.internal.getWindowSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setMouseCursor(engine: *Engine, cursor: enums.MouseCursor) !void {
|
||||||
|
try engine.internal.setMouseCursor(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hasEvent(engine: *Engine) bool {
|
pub fn hasEvent(engine: *Engine) bool {
|
||||||
return engine.internal.hasEvent();
|
return engine.internal.hasEvent();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,19 @@ pub const VSyncMode = enum {
|
||||||
triple,
|
triple,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const MouseCursor = enum {
|
||||||
|
arrow,
|
||||||
|
ibeam,
|
||||||
|
crosshair,
|
||||||
|
pointing_hand,
|
||||||
|
resize_ew,
|
||||||
|
resize_ns,
|
||||||
|
resize_nwse,
|
||||||
|
resize_nesw,
|
||||||
|
resize_all,
|
||||||
|
not_allowed,
|
||||||
|
};
|
||||||
|
|
||||||
pub const MouseButton = enum {
|
pub const MouseButton = enum {
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,24 @@ const mach = {
|
||||||
window.dispatchEvent(new Event("mach-close"));
|
window.dispatchEvent(new Event("mach-close"));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
machSetMouseCursor(cursor_ptr, len) {
|
||||||
|
let mach_name = mach.getString(cursor_ptr, len);
|
||||||
|
|
||||||
|
if (mach_name === 'arrow') document.body.style.cursor = 'default';
|
||||||
|
else if (mach_name === 'ibeam') document.body.style.cursor = 'text';
|
||||||
|
else if (mach_name === 'crosshair') document.body.style.cursor = 'crosshair';
|
||||||
|
else if (mach_name === 'pointing_hand') document.body.style.cursor = 'pointer';
|
||||||
|
else if (mach_name === 'resize_ew') document.body.style.cursor = 'ew-resize';
|
||||||
|
else if (mach_name === 'resize_ns') document.body.style.cursor = 'ns-resize';
|
||||||
|
else if (mach_name === 'resize_nwse') document.body.style.cursor = 'nwse-resize';
|
||||||
|
else if (mach_name === 'resize_nesw') document.body.style.cursor = 'nesw-resize';
|
||||||
|
else if (mach_name === 'resize_all') document.body.style.cursor = 'move';
|
||||||
|
else if (mach_name === 'not_allowed') document.body.style.cursor = 'not-allowed';
|
||||||
|
else {
|
||||||
|
console.log("machSetMouseCursor failed for " + mach_name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
machSetWaitEvent(timeout) {
|
machSetWaitEvent(timeout) {
|
||||||
mach.wait_event_timeout = timeout;
|
mach.wait_event_timeout = timeout;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ pub const Platform = struct {
|
||||||
last_position: glfw.Window.Pos,
|
last_position: glfw.Window.Pos,
|
||||||
wait_event_timeout: f64 = 0.0,
|
wait_event_timeout: f64 = 0.0,
|
||||||
|
|
||||||
|
cursors: [@typeInfo(enums.MouseCursor).Enum.fields.len]?glfw.Cursor = undefined,
|
||||||
|
cursors_tried: [@typeInfo(enums.MouseCursor).Enum.fields.len]bool =
|
||||||
|
[_]bool{false} ** @typeInfo(enums.MouseCursor).Enum.fields.len,
|
||||||
|
|
||||||
native_instance: gpu.NativeInstance,
|
native_instance: gpu.NativeInstance,
|
||||||
|
|
||||||
const EventQueue = std.TailQueue(structs.Event);
|
const EventQueue = std.TailQueue(structs.Event);
|
||||||
|
|
@ -184,6 +188,14 @@ pub const Platform = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deinit(platform: *Platform) void {
|
||||||
|
for (platform.cursors) |glfw_cursor| {
|
||||||
|
if (glfw_cursor) |cur| {
|
||||||
|
cur.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn pushEvent(platform: *Platform, event: structs.Event) void {
|
fn pushEvent(platform: *Platform, event: structs.Event) void {
|
||||||
const node = platform.allocator.create(EventNode) catch unreachable;
|
const node = platform.allocator.create(EventNode) catch unreachable;
|
||||||
node.* = .{ .data = event };
|
node.* = .{ .data = event };
|
||||||
|
|
@ -318,6 +330,39 @@ pub const Platform = struct {
|
||||||
return platform.last_window_size;
|
return platform.last_window_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setMouseCursor(platform: *Platform, cursor: enums.MouseCursor) !void {
|
||||||
|
// Try to create glfw standard cursor, but could fail. In the future
|
||||||
|
// we hope to provide custom backup images for these.
|
||||||
|
// See https://github.com/hexops/mach/pull/352 for more info
|
||||||
|
|
||||||
|
const enum_int = @enumToInt(cursor);
|
||||||
|
const tried = platform.cursors_tried[enum_int];
|
||||||
|
if (!tried) {
|
||||||
|
platform.cursors_tried[enum_int] = true;
|
||||||
|
platform.cursors[enum_int] = switch (cursor) {
|
||||||
|
.arrow => glfw.Cursor.createStandard(.arrow) catch null,
|
||||||
|
.ibeam => glfw.Cursor.createStandard(.ibeam) catch null,
|
||||||
|
.crosshair => glfw.Cursor.createStandard(.crosshair) catch null,
|
||||||
|
.pointing_hand => glfw.Cursor.createStandard(.pointing_hand) catch null,
|
||||||
|
.resize_ew => glfw.Cursor.createStandard(.resize_ew) catch null,
|
||||||
|
.resize_ns => glfw.Cursor.createStandard(.resize_ns) catch null,
|
||||||
|
.resize_nwse => glfw.Cursor.createStandard(.resize_nwse) catch null,
|
||||||
|
.resize_nesw => glfw.Cursor.createStandard(.resize_nesw) catch null,
|
||||||
|
.resize_all => glfw.Cursor.createStandard(.resize_all) catch null,
|
||||||
|
.not_allowed => glfw.Cursor.createStandard(.not_allowed) catch null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platform.cursors[enum_int]) |cur| {
|
||||||
|
try platform.window.setCursor(cur);
|
||||||
|
} else {
|
||||||
|
// TODO: In the future we shouldn't hit this because we'll provide backup
|
||||||
|
// custom cursors.
|
||||||
|
// See https://github.com/hexops/mach/pull/352 for more info
|
||||||
|
std.debug.print("mach: setMouseCursor: {s} not yet supported\n", .{cursor});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hasEvent(platform: *Platform) bool {
|
pub fn hasEvent(platform: *Platform) bool {
|
||||||
return platform.events.first != null;
|
return platform.events.first != null;
|
||||||
}
|
}
|
||||||
|
|
@ -496,6 +541,7 @@ pub fn main() !void {
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
var engine = try Engine.init(allocator);
|
var engine = try Engine.init(allocator);
|
||||||
|
defer engine.internal.deinit();
|
||||||
var app: App = undefined;
|
var app: App = undefined;
|
||||||
|
|
||||||
try app.init(&engine);
|
try app.init(&engine);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ const js = struct {
|
||||||
extern fn machCanvasGetWindowHeight(canvas: CanvasId) u32;
|
extern fn machCanvasGetWindowHeight(canvas: CanvasId) u32;
|
||||||
extern fn machCanvasGetFramebufferWidth(canvas: CanvasId) u32;
|
extern fn machCanvasGetFramebufferWidth(canvas: CanvasId) u32;
|
||||||
extern fn machCanvasGetFramebufferHeight(canvas: CanvasId) u32;
|
extern fn machCanvasGetFramebufferHeight(canvas: CanvasId) u32;
|
||||||
|
extern fn machSetMouseCursor(cursor_name: [*]const u8, len: u32) void;
|
||||||
extern fn machEmitCloseEvent() void;
|
extern fn machEmitCloseEvent() void;
|
||||||
extern fn machSetWaitEvent(timeout: f64) void;
|
extern fn machSetWaitEvent(timeout: f64) void;
|
||||||
extern fn machHasEvent() bool;
|
extern fn machHasEvent() bool;
|
||||||
|
|
@ -84,6 +85,11 @@ pub const Platform = struct {
|
||||||
return platform.last_window_size;
|
return platform.last_window_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setMouseCursor(_: *Platform, cursor: enums.MouseCursor) !void {
|
||||||
|
const cursor_name = @tagName(cursor);
|
||||||
|
js.machSetMouseCursor(cursor_name.ptr, cursor_name.len);
|
||||||
|
}
|
||||||
|
|
||||||
fn pollChanges(platform: *Platform) void {
|
fn pollChanges(platform: *Platform) void {
|
||||||
const change_type = js.machChangeShift();
|
const change_type = js.machChangeShift();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue