@@ -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};
@@ -46,11 +51,16 @@ pub fn init() !void {
4651var globalWindow : ? * Window = null ;
4752
4853pub const Window = struct {
54+ peer : * GuiWidget ,
4955 child : ? PeerType = null ,
5056 scale : f32 = 1.0 ,
5157
58+ pub usingnamespace Events (Window );
59+
5260 pub fn create () ! Window {
53- return Window {};
61+ return Window {
62+ .peer = try GuiWidget .init (Window , lasting_allocator , "div" , "window" ),
63+ };
5464 }
5565
5666 pub fn show (self : * Window ) void {
@@ -106,6 +116,7 @@ pub fn Events(comptime T: type) type {
106116 }
107117
108118 pub inline fn setCallback (self : * T , comptime eType : EventType , cb : anytype ) ! void {
119+ self .peer .object = self ;
109120 switch (eType ) {
110121 .Click = > self .peer .user .clickHandler = cb ,
111122 .Draw = > self .peer .user .drawHandler = cb ,
@@ -119,6 +130,7 @@ pub fn Events(comptime T: type) type {
119130 },
120131 .KeyType = > self .peer .user .keyTypeHandler = cb ,
121132 .KeyPress = > self .peer .user .keyPressHandler = cb ,
133+ .PropertyChange = > self .peer .user .propertyChangeHandler = cb ,
122134 }
123135 }
124136
@@ -181,18 +193,18 @@ pub fn Events(comptime T: type) type {
181193 },
182194 }
183195 } else if (T == Container ) { // if we're a container, iterate over our children to propagate the event
184- for (self .children .items ) | child | {
196+ for (self .peer . children .items ) | child | {
185197 child .processEventFn (child .object , event );
186198 }
187199 }
188200 }
189201
190202 pub fn getWidth (self : * const T ) c_int {
191- return std . math . max (10 , js .getWidth (self .peer .element ));
203+ return @ max (10 , js .getWidth (self .peer .element ));
192204 }
193205
194206 pub fn getHeight (self : * const T ) c_int {
195- return std . math . max (10 , js .getHeight (self .peer .element ));
207+ return @ max (10 , js .getHeight (self .peer .element ));
196208 }
197209
198210 pub fn getPreferredSize (self : * const T ) lib.Size {
@@ -241,7 +253,7 @@ pub const TextField = struct {
241253pub const Label = struct {
242254 peer : * GuiWidget ,
243255 /// The text returned by getText(), it's invalidated everytime setText is called
244- temp_text : ? [: 0 ]const u8 = null ,
256+ temp_text : ? []const u8 = null ,
245257
246258 pub usingnamespace Events (Label );
247259
@@ -375,6 +387,11 @@ pub const Canvas = struct {
375387 js .rectPath (self .ctx , x , y , w , h );
376388 }
377389
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 );
393+ }
394+
378395 pub fn text (self : * DrawContext , x : i32 , y : i32 , layout : TextLayout , str : []const u8 ) void {
379396 // TODO: layout
380397 _ = layout ;
@@ -447,20 +464,28 @@ pub const ImageData = struct {
447464
448465pub const Container = struct {
449466 peer : * GuiWidget ,
450- children : std .ArrayList (* GuiWidget ),
451467
452468 pub usingnamespace Events (Container );
453469
454470 pub fn create () ! Container {
455471 return Container {
456472 .peer = try GuiWidget .init (Container , lasting_allocator , "div" , "container" ),
457- .children = std .ArrayList (* GuiWidget ).init (lasting_allocator ),
458473 };
459474 }
460475
461476 pub fn add (self : * Container , peer : PeerType ) void {
462477 js .appendElement (self .peer .element , peer .element );
463- 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 ;
464489 }
465490
466491 pub fn move (self : * const Container , peer : PeerType , x : u32 , y : u32 ) void {
@@ -498,22 +523,28 @@ pub const HttpResponse = struct {
498523
499524// Execution
500525
501- fn executeMain () callconv ( .Async ) void {
502- const mainFn = @import ("root" ).main ;
503- const ReturnType = @typeInfo (@TypeOf (mainFn )).Fn .return_type .? ;
526+ fn executeStart ( ) void {
527+ const startFn = @import ("root" ).start ;
528+ const ReturnType = @typeInfo (@TypeOf (startFn )).Fn .return_type .? ;
504529 if (ReturnType == void ) {
505- mainFn ();
530+ startFn ();
506531 } else {
507- mainFn () catch | err | @panic (@errorName (err ));
532+ startFn () catch | err | @panic (@errorName (err ));
508533 }
509- js .stopExecution ();
510534}
511535
512- var frame : @Frame (executeMain ) = undefined ;
513- var result : void = {};
514- var suspending : bool = false ;
515-
516- var resumePtr : anyframe = undefined ;
536+ fn executeStep () void {
537+ // Check for events
538+ while (js .hasEvent ()) {
539+ const eventId = js .popEvent ();
540+ if (globalWindow ) | window | {
541+ if (window .child ) | child | {
542+ child .processEventFn (child .object , eventId );
543+ }
544+ }
545+ }
546+ lib .eventStep .callListeners ();
547+ }
517548
518549fn milliTimestamp () i64 {
519550 return @as (i64 , @intFromFloat (js .now ()));
@@ -556,10 +587,11 @@ pub const backendExport = struct {
556587
557588 const start = milliTimestamp ();
558589 while (milliTimestamp () < start + @as (i64 , @intCast (duration ))) {
559- suspending = true ;
560- suspend {
561- resumePtr = @frame ();
562- }
590+ // TODO: when zig async is restored, use suspend here
591+ // suspending = true;
592+ // suspend {
593+ // resumePtr = @frame();
594+ // }
563595 }
564596 return 0 ;
565597 }
@@ -596,41 +628,35 @@ pub const backendExport = struct {
596628 }
597629
598630 pub fn panic (msg : []const u8 , _ : ? * std.builtin.StackTrace , _ : ? usize ) noreturn {
631+ @setRuntimeSafety (false );
599632 js .print (msg );
600633
601634 //@breakpoint();
602635 js .stopExecution ();
603636 }
604637
605638 pub export fn _start () callconv (.C ) void {
606- _ = @asyncCall ( & frame , & result , executeMain , .{} );
639+ executeStart ( );
607640 }
608641
609- pub export fn _zgtContinue () callconv (.C ) void {
610- if (suspending ) {
611- suspending = false ;
612- resume resumePtr ;
613- }
642+ pub export fn _capyStep () callconv (.C ) void {
643+ executeStep ();
614644 }
615645};
616646
617- pub fn runStep (step : shared.EventLoopStep ) callconv (.Async ) bool {
618- _ = step ;
619- while (js .hasEvent ()) {
620- const eventId = js .popEvent ();
621- switch (js .getEventType (eventId )) {
622- else = > {
623- if (globalWindow ) | window | {
624- if (window .child ) | child | {
625- child .processEventFn (child .object , eventId );
626- }
627- }
628- },
629- }
630- }
631- suspending = true ;
632- suspend {
633- resumePtr = @frame ();
634- }
635- return true ;
636- }
647+ // pub fn runStep(step: shared.EventLoopStep) callconv(.Async) bool {
648+ // _ = step;
649+ // while (js.hasEvent()) {
650+ // const eventId = js.popEvent();
651+ // switch (js.getEventType(eventId)) {
652+ // else => {
653+ // if (globalWindow) |window| {
654+ // if (window.child) |child| {
655+ // child.processEventFn(child.object, eventId);
656+ // }
657+ // }
658+ // },
659+ // }
660+ // }
661+ // return true;
662+ // }
0 commit comments