Skip to content

Commit

Permalink
Implement applyConfigStruct
Browse files Browse the repository at this point in the history
  • Loading branch information
zenith391 committed Oct 7, 2023
1 parent 948d5c7 commit 7ec0488
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 49 deletions.
2 changes: 1 addition & 1 deletion examples/demo.zig
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fn drawRounded(cnv: *anyopaque, ctx: *capy.DrawContext) !void {
ctx.setColor(0.7, 0.9, 0.3);
ctx.setLinearGradient(.{ .x0 = 80, .y0 = 0, .x1 = 100, .y1 = 100, .stops = &.{
.{ .offset = 0.1, .color = capy.Color.yellow },
.{ .offset = 0.8, .color = capy.Color.white },
.{ .offset = 0.8, .color = capy.Color.red },
} });
ctx.roundedRectangleEx(
0,
Expand Down
6 changes: 3 additions & 3 deletions examples/fade.zig
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ pub fn main() !void {
capy.expanded((try capy.row(.{}, .{
capy.label(.{ .text = "Hello Zig" }),
capy.expanded(
capy.image(.{ .url = "asset:///ziglogo.png", .scaling = .Fit }),
capy.image(.{ .url = "asset:///ziglogo.png", .scaling = .Fit, .opacity = 0 })
.bind("opacity", &opacity),
),
}))
.bind("opacity", &opacity)),
}))),
capy.button(.{ .label = "Hide", .onclick = startAnimation }),
}),
);
Expand Down
4 changes: 2 additions & 2 deletions examples/time-feed.zig
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn onSubmit(_: *anyopaque) !void {
try list_model.add(.{
.start = @as(u64, @intCast(std.time.timestamp() - 1000)),
.end = @as(u64, @intCast(std.time.timestamp())),
.description = submitDesc.get(),
.description = try capy.internal.lasting_allocator.dupe(u8, submitDesc.get()),
});

// clear description
Expand All @@ -72,7 +72,7 @@ pub fn InsertCard() anyerror!capy.Container {

return try capy.column(.{}, .{
// TODO: TextArea when it supports data wrappers
capy.textField(.{ .name = "description" })
capy.textArea(.{ .name = "description" })
.bind("text", &submitDesc), // placeholder = "Task description..."
capy.label(.{ .text = "Going on since.. 00:00:20" }),
capy.alignment(.{ .x = 1 }, capy.row(.{}, .{
Expand Down
7 changes: 1 addition & 6 deletions src/components/Button.zig
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,7 @@ pub const Button = struct {

pub fn button(config: Button.Config) Button {
var btn = Button.init();
btn.label.set(config.label);
btn.enabled.set(config.enabled);
btn.widget_data.atoms.name.set(config.name);
if (config.onclick) |onclick| {
btn.addClickHandler(onclick) catch unreachable; // TODO: improve
}
@import("../internal.zig").applyConfigStruct(&btn, config);
return btn;
}

Expand Down
14 changes: 2 additions & 12 deletions src/components/Canvas.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,7 @@ pub const Canvas = struct {

pub fn canvas(config: Canvas.Config) Canvas {
var cnv = Canvas.init();
cnv.preferredSize = Atom(?Size).of(config.preferredSize);
cnv.widget_data.atoms.name.set(config.name);
if (config.onclick) |onclick| {
cnv.addClickHandler(onclick) catch unreachable; // TODO: improve
}
if (config.ondraw) |ondraw| {
cnv.addDrawHandler(ondraw) catch unreachable; // TODO: improve
}
@import("../internal.zig").applyConfigStruct(&cnv, config);
return cnv;
}

Expand Down Expand Up @@ -108,10 +101,7 @@ pub const Rect = struct {
pub fn rect(config: Rect.Config) Rect {
var r = Rect.init();
r.addDrawHandler(&Rect.draw) catch unreachable;
r.preferredSize = Atom(?Size).of(config.preferredSize);
r.color = Atom(Color).of(config.color);
r.cornerRadius = Atom([4]f32).of(config.cornerRadius);
r.widget_data.atoms.name.set(config.name);
@import("../internal.zig").applyConfigStruct(&r, config);
return r;
}

Expand Down
8 changes: 1 addition & 7 deletions src/components/CheckBox.zig
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,6 @@ pub const CheckBox = struct {

pub fn checkBox(config: CheckBox.Config) CheckBox {
var btn = CheckBox.init();
btn.checked.set(config.checked);
btn.label.set(config.label);
btn.enabled.set(config.enabled);
btn.widget_data.atoms.name.set(config.name);
if (config.onclick) |onclick| {
btn.addClickHandler(onclick) catch unreachable; // TODO: improve
}
@import("../internal.zig").applyConfigStruct(&btn, config);
return btn;
}
10 changes: 3 additions & 7 deletions src/components/Image.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,9 @@ pub const Image = struct {

// TODO: just directly accept an URL or file path if there's no data
pub fn init(config: Image.Config) Image {
var self = Image.init_events(Image{
.url = Atom([]const u8).of(config.url),
.data = Atom(?ImageData).of(config.data),
.scaling = Atom(Scaling).of(config.scaling),
});
var self = Image.init_events(Image{ .url = Atom([]const u8).of(config.url) });
self.addDrawHandler(&Image.draw) catch unreachable;
@import("../internal.zig").applyConfigStruct(&self, config);
return self;
}

Expand Down Expand Up @@ -147,6 +144,5 @@ pub const Image = struct {
};

pub fn image(config: Image.Config) Image {
var img = Image.init(config);
return img;
return Image.init(config);
}
7 changes: 3 additions & 4 deletions src/components/Label.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ pub const Label = struct {
alignment: Atom(TextAlignment) = Atom(TextAlignment).of(.Left),

pub fn init(config: Label.Config) Label {
return Label.init_events(Label{
.text = Atom([]const u8).of(config.text),
.alignment = Atom(TextAlignment).of(config.alignment),
});
var lbl = Label.init_events(Label{});
@import("../internal.zig").applyConfigStruct(&lbl, config);
return lbl;
}

pub fn _pointerMoved(self: *Label) void {
Expand Down
2 changes: 1 addition & 1 deletion src/image.zig
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub const ImageData = struct {
/// Load from a png file using a buffer (which can be provided by @embedFile)
pub fn fromBuffer(allocator: std.mem.Allocator, buf: []const u8) !ImageData {
// stage1 crashes with LLVM ERROR: Unable to expand fixed point multiplication.
//const img = try zigimg.Image.fromMemory(allocator, buf);
// const img = try zigimg.Image.fromMemory(allocator, buf);

var stream = std.io.StreamSource{ .const_buffer = std.io.fixedBufferStream(buf) };
return readFromStream(allocator, &stream);
Expand Down
36 changes: 30 additions & 6 deletions src/internal.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const Widget = @import("widget.zig").Widget;
const Class = @import("widget.zig").Class;
const Size = dataStructures.Size;
const Atom = dataStructures.Atom;
const Container_Impl = @import("containers.zig").Container_Impl;
const Container = @import("containers.zig").Container;
const Layout = @import("containers.zig").Layout;
const MouseButton = @import("backends/shared.zig").MouseButton;

Expand Down Expand Up @@ -175,7 +175,7 @@ pub fn Widgeting(comptime T: type) type {
} else {
comptime {
var compileError: []const u8 = "No such property: " ++ name;
if (T == Container_Impl) {
if (T == Container) {
compileError = compileError ++ ", did you mean to use getChild() ?";
}
@compileError(compileError);
Expand Down Expand Up @@ -317,9 +317,32 @@ fn iterateFields(comptime config_fields: *[]const std.builtin.Type.StructField,
}
}

pub fn applyConfigStruct(target: anytype, config: anytype) void {
_ = target;
_ = config;
/// target is a pointer to a component
/// config is a config struct generated by GenerateConfigStruct(T)
pub fn applyConfigStruct(target: anytype, config: GenerateConfigStruct(std.meta.Child(@TypeOf(target)))) void {
std.debug.assert(std.meta.trait.isPtrTo(.Struct)(@TypeOf(target)));
iterateApplyFields(std.meta.Child(@TypeOf(target)), target, config);

if (config.onclick) |onclick| {
target.addClickHandler(onclick) catch unreachable; // TODO: improve
}
if (config.ondraw) |ondraw| {
target.addDrawHandler(ondraw) catch unreachable; // TODO: improve
}
}

fn iterateApplyFields(comptime T: type, target: anytype, config: GenerateConfigStruct(T)) void {
inline for (std.meta.fields(std.meta.Child(@TypeOf(target)))) |field| {
const FieldType = field.type;
if (comptime dataStructures.isAtom(FieldType)) {
const name = field.name;
@field(target, field.name).set(
@field(config, name),
);
} else if (comptime std.meta.trait.is(.Struct)(FieldType)) {
iterateApplyFields(T, &@field(target, field.name), config);
}
}
}

/// If T is a pointer, return the type it points to, otherwise return T.
Expand Down Expand Up @@ -349,7 +372,7 @@ pub fn genericWidgetFrom(component: anytype) anyerror!Widget {
break :blk copy;
};

// Udate things like data wrappers, this happens once, at initialization,
// Update things like data wrappers, this happens once, at initialization,
// after that the component isn't moved in memory anymore
cp.pointerMoved();

Expand Down Expand Up @@ -555,6 +578,7 @@ pub fn Events(comptime T: type) type {
/// When the value is changed in the opacity data wrapper
fn opacityChanged(newValue: f32, userdata: usize) void {
const widget = @as(*T, @ptrFromInt(userdata));
std.log.info("opaccity changed to {d}", .{newValue});
if (widget.peer) |*peer| {
peer.setOpacity(newValue);
}
Expand Down

0 comments on commit 7ec0488

Please sign in to comment.