diff --git a/README.md b/README.md index d7af27f..98a5a80 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,150 @@ +# Another render agnostic immedate mode ui layout libary +Shoots is another render agnostic immedate mode ui layout libary but this time written in zig. +you can check out examples for how the libary works, but here are the basic principles: +everything is a node: +```zig +const root = UI.Element(.{ + .name = "button", + .rect = .{ + .h = 20, + .w = 60, + }, + .on_click = .{ + .func = &updateButton, + .data = &.{}, + }, + .on_hover = .{ + .func = &hoverButton, + .data = &.{}, + }, + .style = .{ + .background_colour = .{ + .g = 255, + }, + .rounded = 25, + }, + }, + .children = &[_]UI.Node{ + UI.Txt( + UI.Text.init( + "hello world", + try rl.getFontDefault(), + .{}, + ), + ), + UI.Txt( + UI.Text.init( + "hello world again", + try rl.getFontDefault(), + .{}, + ).setBackground(.{ + .a = 255, + .g = 255, + }), + ), + }, +}); +``` -## resources: -[NZ How Clay's UI Layout Algorithm Works](https://www.youtube.com/watch?v=by9lQvpvMIc) - https://www.youtube.com/watch?v=Z1qyvQsjK5Y +there are 3 differnt types of nodes +- elements + these are basically your html divs +- text + text is currently just one line +- textures + all the fun images you want to include - https://tchayen.com/how-to-write-a-flexbox-layout-engine +once you have your node tree setup you should create an arena allocator, since on each render a clone of the node tree will be created this is to ensure that its a forgetful ui system. +```zig +var al = std.heap.ArenaAllocator.init(std.heap.smp_allocator); +``` +now using the arena you can either use: +```zig + +var sized = try UI.resolveSizing(al.allocator(), root); + +OR +// clone the root node +var new_tree: Node = try UI.deepClone(root, alloc); + +// this is needed as a place holder for the root node +var base_node: Node = Node{ .element = Ele{ + .children = &[_]Node{ + root, + }, +} }; +// go through and computes the sizes of all the child elements +computeSizes(&new_tree, &base_node); + +// grows the child elements +computeGrowElements(&new_tree); + +// computes the pos +computePositions(&new_tree); + +``` +This will clone the tree, compute the sizes of the rectangles compute, grow all the child elements, and lastly compute all the positions of the nodes. + +next check for any interactions that may occur, these are things like on hover and on click: +```zig +const needs_redrawn = UI.processInteractions(&sized, .{ + .pos = .{ + .x = mouse_pos.x, + .y = mouse_pos.y, + }, + .left = rl.isMouseButtonDown(.left), + .middle = rl.isMouseButtonDown(.middle), + .right = rl.isMouseButtonDown(.right), +}); +``` +this function returns a bool to determin if the current tree needs to be redrawn, this should be useful in some case. + +and finally you can generate the render commands, these commands tell your render where to draw the rectangles on the screen. + +```zig +const commands = try UI.getRenderCommands(sized, al.allocator()); +``` + +you can checkout [the raylib example for how to parse these render commands](./examples/raylib-example/src/main.zig) + +and finally free the arena with a retained_capacity as the ui will more then likely be the exact same size and should only require some few addtional allocs. + +``` +_ = al.reset(.retain_capacity); +``` + +## adding shoots to your project + +fetch the repo +``` +> zig fetch --save git+[link] +``` + +add to build.zig + +```zig + +const shoots = b.dependency("shoots", .{ + .target = target, + .optimize = optimize, +}); + +exe.root_module.addImport("shoots", shoots.module("shoots")); + +``` + +## resources if you want to either learn out Immediate-Mode ui or make your own: +- [How Clay's UI Layout Algorithm Works](https://www.youtube.com/watch?v=by9lQvpvMIc) + really good for the layout algrothim - https://github.com/rxi/microui +- [Immediate-Mode Graphical User Interfaces - 2005](https://www.youtube.com/watch?v=Z1qyvQsjK5Y) + good video on explaining the concepts behind immediate mode guis + +- [how-to-write-a-flexbox-layout-engine](https://tchayen.com/how-to-write-a-flexbox-layout-engine) + perfect for getting an overview of how all the componets togeather + +- [microui](https://github.com/rxi/microui) + some further inporation for how to create ui frameworks +