Skip to content

Commit 5025df4

Browse files
authored
Merge branch 'master' into wasm-no-async
2 parents b8c7de8 + b222a37 commit 5025df4

File tree

12 files changed

+294
-98
lines changed

12 files changed

+294
-98
lines changed

.gitmodules

Lines changed: 0 additions & 4 deletions
This file was deleted.

build_capy.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ const WebServerStep = struct {
9595
content_type = "application/wasm";
9696
}
9797

98-
std.log.info("{s} -> {s}", .{ path, file_path });
98+
std.log.info("{s}", .{path});
9999
const file: ?std.fs.File = std.fs.cwd().openFile(file_path, .{ .mode = .read_only }) catch |err| blk: {
100100
switch (err) {
101101
error.FileNotFound => break :blk null,

examples/colors.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn animateRandomColor(button_: *anyopaque) !void {
1515
rect.color.animate(capy.Easings.InOut, randomColor, 1000);
1616
}
1717

18-
pub fn main() !void {
18+
pub fn start() !void {
1919
try capy.init();
2020
var window = try capy.Window.init();
2121
prng = std.rand.DefaultPrng.init(@as(u64, @bitCast(std.time.milliTimestamp())));
@@ -28,5 +28,5 @@ pub fn main() !void {
2828
}),
2929
}));
3030
window.show();
31-
capy.runEventLoop();
31+
// capy.runEventLoop();
3232
}

examples/test-backend.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ pub fn main() !void {
99
try window.set(
1010
capy.row(.{}, .{}),
1111
);
12-
var row = capy.label(.{ .text = "test" });
13-
_ = row;
1412

1513
// window.resize(800, 450);
1614
window.show();

src/backends/macos/AppKit.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub const NSWindowStyleMask = struct {
99
pub const Resizable: NSUInteger = 1 << 3;
1010
pub const Utility: NSUInteger = 1 << 4;
1111
pub const FullScreen: NSUInteger = 1 << 14;
12+
pub const FullSizeContentView: NSUInteger = 1 << 15;
1213
};
1314

1415
pub const NSBackingStore = enum(NSUInteger) {

src/backends/macos/backend.zig

Lines changed: 107 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ const EventFunctions = shared.EventFunctions(@This());
88
const EventType = shared.BackendEventType;
99
const BackendError = shared.BackendError;
1010
const MouseButton = shared.MouseButton;
11-
//pub const PeerType = *c.GtkWidget;
12-
pub const PeerType = *opaque {};
11+
12+
// pub const PeerType = *opaque {};
13+
pub const PeerType = objc.id;
1314

1415
var activeWindows = std.atomic.Atomic(usize).init(0);
1516
var hasInit: bool = false;
@@ -40,14 +41,62 @@ pub const EventUserData = struct {
4041
focusOnClick: bool = false,
4142
};
4243

44+
var test_data = EventUserData{ .peer = undefined };
4345
pub inline fn getEventUserData(peer: PeerType) *EventUserData {
4446
_ = peer;
47+
return &test_data;
4548
//return @ptrCast(*EventUserData, @alignCast(@alignOf(EventUserData), c.g_object_get_data(@ptrCast(*c.GObject, peer), "eventUserData").?));
4649
}
4750

4851
pub fn Events(comptime T: type) type {
49-
_ = T;
50-
return struct {};
52+
return struct {
53+
const Self = @This();
54+
55+
pub fn setUserData(self: *T, data: anytype) void {
56+
comptime {
57+
if (!std.meta.trait.isSingleItemPtr(@TypeOf(data))) {
58+
@compileError(std.fmt.comptimePrint("Expected single item pointer, got {s}", .{@typeName(@TypeOf(data))}));
59+
}
60+
}
61+
62+
getEventUserData(self.peer).userdata = @intFromPtr(data);
63+
}
64+
65+
pub inline fn setCallback(self: *T, comptime eType: EventType, cb: anytype) !void {
66+
const data = &getEventUserData(self.peer).user;
67+
switch (eType) {
68+
.Click => data.clickHandler = cb,
69+
.Draw => data.drawHandler = cb,
70+
.MouseButton => data.mouseButtonHandler = cb,
71+
.MouseMotion => data.mouseMotionHandler = cb,
72+
.Scroll => data.scrollHandler = cb,
73+
.TextChanged => data.changedTextHandler = cb,
74+
.Resize => data.resizeHandler = cb,
75+
.KeyType => data.keyTypeHandler = cb,
76+
.KeyPress => data.keyPressHandler = cb,
77+
.PropertyChange => data.propertyChangeHandler = cb,
78+
}
79+
}
80+
81+
pub fn setOpacity(self: *const T, opacity: f32) void {
82+
_ = opacity;
83+
_ = self;
84+
}
85+
86+
pub fn getWidth(self: *const T) u32 {
87+
_ = self;
88+
return 100;
89+
}
90+
91+
pub fn getHeight(self: *const T) u32 {
92+
_ = self;
93+
return 100;
94+
}
95+
96+
pub fn deinit(self: *const T) void {
97+
_ = self;
98+
}
99+
};
51100
}
52101

53102
pub const Window = struct {
@@ -59,8 +108,8 @@ pub const Window = struct {
59108

60109
pub fn create() BackendError!Window {
61110
const NSWindow = objc.getClass("NSWindow") catch return BackendError.InitializationError;
62-
const rect = objc.NSRectMake(100, 100, 200, 200);
63-
const style = AppKit.NSWindowStyleMask.Titled | AppKit.NSWindowStyleMask.Closable | AppKit.NSWindowStyleMask.Miniaturizable | AppKit.NSWindowStyleMask.Resizable;
111+
const rect = objc.NSRect.make(100, 100, 200, 200);
112+
const style = AppKit.NSWindowStyleMask.Titled | AppKit.NSWindowStyleMask.Closable | AppKit.NSWindowStyleMask.Miniaturizable | AppKit.NSWindowStyleMask.Resizable | AppKit.NSWindowStyleMask.FullSizeContentView;
64113

65114
std.log.info("make new rect", .{});
66115
const newRect = objc.msgSendByName(objc.NSRect, NSWindow, "frameRectForContentRect:styleMask:", .{ rect, style }) catch unreachable;
@@ -82,7 +131,12 @@ pub const Window = struct {
82131
}
83132

84133
pub fn resize(self: *Window, width: c_int, height: c_int) void {
85-
const frame = objc.NSRectMake(100, 100, @as(objc.CGFloat, @floatFromInt(width)), @as(objc.CGFloat, @floatFromInt(height)));
134+
const frame = objc.NSRect.make(
135+
100,
136+
100,
137+
@as(objc.CGFloat, @floatFromInt(width)),
138+
@as(objc.CGFloat, @floatFromInt(height)),
139+
);
86140
// TODO: resize animation can be handled using a DataWrapper on the user-facing API
87141
_ = objc.msgSendByName(void, self.peer, "setFrame:display:", .{ frame, true }) catch unreachable;
88142
}
@@ -106,6 +160,7 @@ pub const Window = struct {
106160

107161
pub fn show(self: *Window) void {
108162
std.log.info("show window", .{});
163+
objc.msgSendByName(void, self.peer, "setIsVisible:", .{ @as(objc.id, self.peer), @as(u8, @intFromBool(true)) }) catch unreachable;
109164
objc.msgSendByName(void, self.peer, "makeKeyAndOrderFront:", .{@as(objc.id, self.peer)}) catch unreachable;
110165
std.log.info("showed window", .{});
111166
_ = activeWindows.fetchAdd(1, .Release);
@@ -117,6 +172,51 @@ pub const Window = struct {
117172
}
118173
};
119174

175+
pub const Container = struct {
176+
peer: objc.id,
177+
178+
pub usingnamespace Events(Container);
179+
180+
pub fn create() BackendError!Container {
181+
return Container{ .peer = undefined };
182+
}
183+
184+
pub fn add(self: *const Container, peer: PeerType) void {
185+
_ = peer;
186+
_ = self;
187+
}
188+
189+
pub fn remove(self: *const Container, peer: PeerType) void {
190+
_ = peer;
191+
_ = self;
192+
}
193+
194+
pub fn move(self: *const Container, peer: PeerType, x: u32, y: u32) void {
195+
_ = y;
196+
_ = x;
197+
_ = peer;
198+
_ = self;
199+
}
200+
201+
pub fn resize(self: *const Container, peer: PeerType, w: u32, h: u32) void {
202+
_ = h;
203+
_ = w;
204+
_ = peer;
205+
_ = self;
206+
}
207+
208+
pub fn setTabOrder(self: *const Container, peers: []const PeerType) void {
209+
_ = peers;
210+
_ = self;
211+
}
212+
};
213+
214+
pub const Canvas = struct {
215+
pub usingnamespace Events(Canvas);
216+
217+
pub const DrawContext = struct {};
218+
};
219+
120220
pub fn postEmptyEvent() void {
121221
@panic("TODO: postEmptyEvent");
122222
}

src/backends/macos/objc.zig

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,36 @@ pub fn msgSend(comptime ReturnType: type, target: anytype, selector: SEL, args:
1313
const FnType = blk: {
1414
{
1515
// TODO(hazeycode): replace this hack with the more generalised code above once it doens't crash the compiler
16-
break :blk switch (args_meta.len) {
16+
break :blk *const switch (args_meta.len) {
1717
0 => fn (@TypeOf(target), SEL) callconv(.C) ReturnType,
18-
1 => fn (@TypeOf(target), SEL, args_meta[0].field_type) callconv(.C) ReturnType,
19-
2 => fn (@TypeOf(target), SEL, args_meta[0].field_type, args_meta[1].field_type) callconv(.C) ReturnType,
20-
3 => fn (@TypeOf(target), SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type) callconv(.C) ReturnType,
21-
4 => fn (@TypeOf(target), SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type, args_meta[3].field_type) callconv(.C) ReturnType,
22-
5 => fn (@TypeOf(target), SEL, args_meta[0].field_type, args_meta[1].field_type, args_meta[2].field_type, args_meta[3].field_type, args_meta[4].field_type) callconv(.C) ReturnType,
18+
1 => fn (@TypeOf(target), SEL, args_meta[0].type) callconv(.C) ReturnType,
19+
2 => fn (@TypeOf(target), SEL, args_meta[0].type, args_meta[1].type) callconv(.C) ReturnType,
20+
3 => fn (@TypeOf(target), SEL, args_meta[0].type, args_meta[1].type, args_meta[2].type) callconv(.C) ReturnType,
21+
4 => fn (@TypeOf(target), SEL, args_meta[0].type, args_meta[1].type, args_meta[2].type, args_meta[3].type) callconv(.C) ReturnType,
22+
5 => fn (@TypeOf(target), SEL, args_meta[0].type, args_meta[1].type, args_meta[2].type, args_meta[3].type, args_meta[4].type) callconv(.C) ReturnType,
2323
else => @compileError("Unsupported number of args: add more variants in zig-objcrt/src/message.zig"),
2424
};
2525
}
2626
};
2727
// NOTE: func is a var because making it const causes a compile error which I believe is a compiler bug
28-
var func = @as(FnType, @ptrCast(c.objc_msgSend));
29-
return @call(.{}, func, .{ target, selector } ++ args);
28+
var func = @as(FnType, @ptrCast(&c.objc_msgSend));
29+
return @call(.auto, func, .{ target, selector } ++ args);
3030
} else {
3131
const FnType = blk: {
3232
{
3333
// TODO(hazeycode): replace this hack with the more generalised code above once it doens't crash the compiler
34-
break :blk switch (args_meta.len) {
34+
break :blk *const switch (args_meta.len) {
3535
0 => fn (*ReturnType, @TypeOf(target), SEL) callconv(.C) void,
36-
1 => fn (*ReturnType, @TypeOf(target), SEL, args_meta[0].field_type) callconv(.C) void,
37-
2 => fn (*ReturnType, @TypeOf(target), SEL, args_meta[0].field_type, args_meta[1].field_type) callconv(.C) void,
36+
1 => fn (*ReturnType, @TypeOf(target), SEL, args_meta[0].type) callconv(.C) void,
37+
2 => fn (*ReturnType, @TypeOf(target), SEL, args_meta[0].type, args_meta[1].type) callconv(.C) void,
3838
else => @compileError("Unsupported number of args: add more variants in zig-objcrt/src/message.zig"),
3939
};
4040
}
4141
};
4242
// NOTE: func is a var because making it const causes a compile error which I believe is a compiler bug
43-
var func = @as(FnType, @ptrCast(c.objc_msgSend_stret));
43+
var func = @as(FnType, @ptrCast(&c.objc_msgSend_stret));
4444
var stret: ReturnType = undefined;
45-
_ = @call(.{}, func, .{ &stret, target, selector } ++ args);
45+
_ = @call(.auto, func, .{ &stret, target, selector } ++ args);
4646
return stret;
4747
}
4848
}
@@ -143,20 +143,13 @@ pub fn getClass(class_name: [:0]const u8) Error!Class {
143143
return c.objc_getClass(class_name) orelse Error.ClassNotRegisteredWithRuntime;
144144
}
145145

146-
pub const CGFloat = switch (@import("builtin").cpu.arch.ptrBitWidth()) {
146+
pub const CGFloat = switch (@import("builtin").target.ptrBitWidth()) {
147147
64 => f64,
148148
32 => f32,
149149
else => unreachable,
150150
};
151151

152152
pub const NSRect = CGRect;
153-
pub const NSRectMake = CGRectMake;
154-
pub fn CGRectMake(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) CGRect {
155-
return CGRect{
156-
.origin = .{ .x = x, .y = y },
157-
.size = .{ .width = width, .height = height },
158-
};
159-
}
160153

161154
pub const CGPoint = extern struct {
162155
x: CGFloat,
@@ -171,4 +164,11 @@ pub const CGSize = extern struct {
171164
pub const CGRect = extern struct {
172165
origin: CGPoint,
173166
size: CGSize,
167+
168+
pub fn make(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) CGRect {
169+
return .{
170+
.origin = .{ .x = x, .y = y },
171+
.size = .{ .width = w, .height = h },
172+
};
173+
}
174174
};

src/backends/wasm/backend.zig

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ const GuiWidget = struct {
2222
element: js.ElementId = 0,
2323

2424
processEventFn: *const fn (object: ?*anyopaque, event: js.EventId) void,
25+
children: std.ArrayList(*GuiWidget),
2526

2627
pub fn init(comptime T: type, allocator: std.mem.Allocator, name: []const u8, typeName: []const u8) !*GuiWidget {
2728
const self = try allocator.create(GuiWidget);
28-
self.* = .{ .processEventFn = T.processEvent, .element = js.createElement(name, typeName) };
29+
self.* = .{
30+
.processEventFn = T.processEvent,
31+
.element = js.createElement(name, typeName),
32+
.children = std.ArrayList(*GuiWidget).init(allocator),
33+
};
2934
return self;
3035
}
3136
};
@@ -111,6 +116,7 @@ pub fn Events(comptime T: type) type {
111116
}
112117

113118
pub inline fn setCallback(self: *T, comptime eType: EventType, cb: anytype) !void {
119+
self.peer.object = self;
114120
switch (eType) {
115121
.Click => self.peer.user.clickHandler = cb,
116122
.Draw => self.peer.user.drawHandler = cb,
@@ -187,7 +193,7 @@ pub fn Events(comptime T: type) type {
187193
},
188194
}
189195
} else if (T == Container) { // if we're a container, iterate over our children to propagate the event
190-
for (self.children.items) |child| {
196+
for (self.peer.children.items) |child| {
191197
child.processEventFn(child.object, event);
192198
}
193199
}
@@ -381,9 +387,9 @@ pub const Canvas = struct {
381387
js.rectPath(self.ctx, x, y, w, h);
382388
}
383389

384-
pub fn roundedRectangleEx(self: *DrawContext, x: i32, y: i32, w: u32, h: u32, cornerRadiuses: [4]f32) void {
385-
_ = cornerRadiuses;
386-
self.rectangle(x, y, w, h);
390+
pub fn roundedRectangleEx(self: *DrawContext, x: i32, y: i32, w: u32, h: u32, corner_radiuses: [4]f32) void {
391+
_ = corner_radiuses;
392+
js.rectPath(self.ctx, x, y, w, h);
387393
}
388394

389395
pub fn text(self: *DrawContext, x: i32, y: i32, layout: TextLayout, str: []const u8) void {
@@ -458,20 +464,28 @@ pub const ImageData = struct {
458464

459465
pub const Container = struct {
460466
peer: *GuiWidget,
461-
children: std.ArrayList(*GuiWidget),
462467

463468
pub usingnamespace Events(Container);
464469

465470
pub fn create() !Container {
466471
return Container{
467472
.peer = try GuiWidget.init(Container, lasting_allocator, "div", "container"),
468-
.children = std.ArrayList(*GuiWidget).init(lasting_allocator),
469473
};
470474
}
471475

472476
pub fn add(self: *Container, peer: PeerType) void {
473477
js.appendElement(self.peer.element, peer.element);
474-
self.children.append(peer) catch unreachable;
478+
self.peer.children.append(peer) catch unreachable;
479+
}
480+
481+
pub fn remove(self: *const Container, peer: PeerType) void {
482+
_ = peer;
483+
_ = self;
484+
}
485+
486+
pub fn setTabOrder(self: *Container, peers: []const PeerType) void {
487+
_ = peers;
488+
_ = self;
475489
}
476490

477491
pub fn remove(self: *const Container, peer: PeerType) void {
@@ -611,10 +625,6 @@ pub const backendExport = struct {
611625

612626
const start = milliTimestamp();
613627
while (milliTimestamp() < start + @as(i64, @intCast(duration))) {
614-
// suspending = true;
615-
// suspend {
616-
// resumePtr = @frame();
617-
// }
618628
// TODO: better way to sleep like calling a jS function for sleep
619629
}
620630
return 0;
@@ -652,6 +662,7 @@ pub const backendExport = struct {
652662
}
653663

654664
pub fn panic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
665+
@setRuntimeSafety(false);
655666
js.print(msg);
656667

657668
//@breakpoint();
@@ -668,7 +679,7 @@ pub const backendExport = struct {
668679
// _ = @asyncCall(&frame, &result, executeMain, .{});
669680
// }
670681

671-
// pub export fn _zgtContinue() callconv(.C) void {
682+
// pub export fn _capyStep() callconv(.C) void {
672683
// if (suspending) {
673684
// suspending = false;
674685
// resume resumePtr;

0 commit comments

Comments
 (0)