aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.odin74
-rw-r--r--src/tafl.odin262
-rw-r--r--src/tafl/tafl.odin355
3 files changed, 429 insertions, 262 deletions
diff --git a/src/main.odin b/src/main.odin
new file mode 100644
index 0000000..0cc699f
--- /dev/null
+++ b/src/main.odin
@@ -0,0 +1,74 @@
+package main
+
+import t "tafl"
+
+
+main :: proc() {
+
+ width, height : i32 = 1920, 1080
+
+ t.start_window(width, height, "tafl test")
+
+ for !t.window_should_close() {
+
+ if t.resized(){
+ width, height = t.get_window_size()
+ }
+
+ {
+ t.tafl(
+ sizing_width=t.FIXED(int(width)),
+ sizing_height=t.FIXED(int(height)),
+ layout=.LEFT_TO_RIGHT,
+ color={.0,.0,.0, 1},
+ padding={16,16,16,16},
+ child_gap=16,
+ )
+ {
+ t.tafl(color={.3,.6,.9, 1},
+ sizing_height=t.GROW,
+ sizing_width=t.FIXED(500))
+
+ {
+ t.tafl(color={.1,.1,.1, 1})
+
+ {
+ t.tafl(color={.1,.1,.1, 1})
+ }
+ {
+ t.tafl(color={.1,.1,.1, 1})
+ }
+ {
+ t.tafl(color={.1,.1,.1, 1})
+ }
+ }
+
+ {
+ t.tafl(color={.1,.1,.1, 1})
+ }
+ }
+
+ {
+ t.tafl(color={.2,.2,.2, 1},
+ sizing_width=t.GROW,
+ sizing_height=t.GROW)
+ }
+ {
+ t.tafl(color={.1,.8,.2, 1},
+ sizing_width=t.FIXED(300),
+ sizing_height=t.GROW,)
+ /*{
+ t.tafl(color={.1,.1,.1, 1})
+ }
+ {
+ t.tafl(color={.1,.1,.1, 1})
+ }*/
+ }
+ /*{
+ t.tafl(color={.1,.1,.1, 1})
+ }*/
+ }
+
+ t.render()
+ }
+}
diff --git a/src/tafl.odin b/src/tafl.odin
deleted file mode 100644
index a582858..0000000
--- a/src/tafl.odin
+++ /dev/null
@@ -1,262 +0,0 @@
-package tafl
-
-import "core:fmt"
-//import "core:math"
-import rl "vendor:raylib"
-
-tafl_elements : [4096]Tafl
-tafl_elements_count : int
-
-tafl_stack : [4096]int
-tafl_stack_depth : int
-
-child_buffer : [4096]int
-child_buffer_len : int
-
-temp_child_buffer : [4096]int
-temp_child_buffer_len : int // May be inferred by child count, and not be needed
-
-main :: proc() {
-
- {
- tafl(color={.1,.1,.1,1})
-
- {
- tafl(color={.1,.1,.1,1})
-
- {
- tafl(color={.1,.1,.1,1})
-
- {
- tafl(color={.1,.1,.1,1})
- }
- {
- tafl(color={.1,.1,.1,1})
- }
- {
- tafl(color={.1,.1,.1,1})
- }
- }
-
- {
- tafl(color={.1,.1,.1,1})
- }
- }
-
- {
- tafl(color={.1,.1,.1,1})
- }
- {
- tafl(color={.1,.1,.1,1})
- {
- tafl(color={.1,.1,.1,1})
- }
- {
- tafl(color={.1,.1,.1,1})
- }
- }
- {
- tafl(color={.1,.1,.1,1})
- }
- }
-}
-
-
-
-@(deferred_out=__tafl_close)
-tafl :: proc(
- /*width : int = 0,
- height : int = 0,
- x : int = 0,
- y : int = 0,*/
- sizing_width : Sizing_Dimension = {.FIT, 0, 0},
- sizing_height : Sizing_Dimension = {.FIT, 0, 0},
- layout : Layout = .LEFT_TO_RIGHT,
- padding : Sides = {0,0,0,0},
- child_gap : int = 0,
- color : Color = {1,1,0,1},
- ) -> ^Tafl{
-
- parent_ptr : ^Tafl = nil
- if tafl_stack_depth > 0 {
- parent_ptr = &tafl_elements[tafl_stack[tafl_stack_depth-1]]
- }
-
- tafl_elements[tafl_elements_count] = {
- /*width = width,
- height = height,
- x = x,
- y = y,*/
- sizing = {sizing_width, sizing_height},
- layout = layout,
- padding = padding,
- child_gap = child_gap,
-
- parent = parent_ptr,
- }
- this_tafl : ^Tafl = &tafl_elements[tafl_elements_count]
-
- tafl_stack[tafl_stack_depth] = tafl_elements_count
- this_tafl.own_index = tafl_elements_count
- this_tafl.own_depth = tafl_stack_depth
- this_tafl.children.index = temp_child_buffer_len
-
- indent(this_tafl.own_depth)
- fmt.printfln("+ Opened tafl {}", this_tafl.own_index)
-
- tafl_elements_count += 1
- tafl_stack_depth += 1
-
- return this_tafl
-}
-
-
-__tafl_close :: proc(tafl : ^Tafl) {
-
- parent := tafl.parent
- if parent != nil {
-
- tafl.width += tafl.padding.left + tafl.padding.right
- tafl.height += tafl.padding.top + tafl.padding.bottom
-
- // Not entirely sure yet, because Nic's video doesn't say you need this
- // max(), but I have a feeling that childless tafls will cause negative
- // total_child_gaps, which would be bad.
- //
- // ALSO: Wtf? Why are we basing this off of the tafls number of siblings?
- // I do not understand this.
- total_child_gap := max(parent.children.len - 1, 0) * parent.child_gap
-
- switch parent.layout {
- case .LEFT_TO_RIGHT:
- tafl.width += total_child_gap
- parent.width += tafl.width
- parent.height = max(tafl.height, parent.height)
- case .TOP_TO_BOTTOM:
- tafl.height += total_child_gap
- parent.height += tafl.height
- parent.width = max(tafl.width, parent.width)
- }
-
- }
-
- for i in 0..<tafl.children.len {
- child_buffer[child_buffer_len+i] = temp_child_buffer[tafl.children.index+i]
- temp_child_buffer_len -= 1
- }
- tafl.children.index = child_buffer_len
- child_buffer_len += tafl.children.len
-
- temp_child_buffer[temp_child_buffer_len] = tafl.own_index
- temp_child_buffer_len += 1
-
- if parent != nil {
- parent.children.len += 1
- } else {
- child_buffer[child_buffer_len] = 0
- child_buffer_len += 1
- }
-
- tafl_stack_depth -= 1
-
- indent(tafl.own_depth)
- fmt.printfln("+ Closed tafl {}\t\tchild_buffer:{}\t\ttemp_child_buffer:{}\tchild_index:{} {}", tafl.own_index, child_buffer[0:child_buffer_len], temp_child_buffer[0:temp_child_buffer_len], tafl.children.index, tafl.children.len)
-}
-
-
-
-grow_children :: proc(parent : ^Tafl) {
- remainingWidth := parent.width
- remainingHeight := parent.height
- remainingWidth -= parent.padding.left + parent.padding.right
- remainingHeight -= parent.padding.top + parent.padding.bottom
-
- for i in 0..<parent.children.len {
- child : ^Tafl = &tafl_elements[child_buffer[parent.children.index+i]]
- remainingWidth -= child.width
- }
- // Do we need to make sure this isn't negative???
- remainingWidth -= (parent.children.len - 1) * parent.child_gap
-
- for i in 0..<parent.children.len {
- child : ^Tafl = &tafl_elements[child_buffer[parent.children.index+i]]
- if child.sizing.width.type == .GROW {
- child.width += remainingWidth
- } else if (child.sizing.height.type == .GROW) {
- child.height += remainingHeight
- }
- }
-}
-
-
-
-
-
-Sizing_Dimension :: struct {
- type : enum{
- FIT,
- GROW,
- FIXED
- },
- min, max : int
-}
-
-Layout :: enum {
- LEFT_TO_RIGHT,
- TOP_TO_BOTTOM,
-}
-
-Sides :: struct {
- top, bottom, left, right : int
-}
-
-Color :: struct {
- r,g,b,a : f32
-}
-
-Tafl :: struct {
- width, height : int,
- x, y : int,
-
- own_index : int, // Delete me
- own_depth : int, // Delete me
-
- parent : ^Tafl,
-
-
-
- // style
-
- children : struct {
- index, len : int
- },
- sizing : struct {
- width : Sizing_Dimension,
- height : Sizing_Dimension,
- },
- layout : Layout,
- padding : Sides,
- child_gap : int,
- color : Color,
-}
-
-Tafl_Style :: struct {
- sizing : struct {
- width : Sizing_Dimension,
- height : Sizing_Dimension,
- },
- layout : Layout,
- padding : Sides,
- child_gap : int,
- color : Color,
-}
-
-indent :: proc(x : int) {
- for _ in 0..<x {
- fmt.print("| ")
- }
-}
-
-GROW : Sizing_Dimension : {.GROW, 0, max(type_of(Sizing_Dimension{}.max))}
-
-FIT : Sizing_Dimension : {.FIT, 0, max(type_of(Sizing_Dimension{}.max))} \ No newline at end of file
diff --git a/src/tafl/tafl.odin b/src/tafl/tafl.odin
new file mode 100644
index 0000000..c816493
--- /dev/null
+++ b/src/tafl/tafl.odin
@@ -0,0 +1,355 @@
+package tafl
+
+import "core:fmt"
+import rl "vendor:raylib"
+
+tafl_elements : [4096]Tafl
+tafl_elements_count : int
+
+tafl_stack : [4096]int
+tafl_stack_depth : int
+
+child_index_buffer : [4096]int
+child_index_buffer_len : int
+
+temp_child_buffer : [4096]int
+temp_child_buffer_len : int // May be inferred by child count, and not be needed
+
+clear_layout :: proc() {
+ tafl_stack_depth = 0
+ tafl_elements_count = 0
+ child_index_buffer_len = 0
+ temp_child_buffer_len = 0
+}
+
+@(deferred_out=__tafl_close)
+tafl :: proc(
+ /*width : int = 0,
+ height : int = 0,
+ x : int = 0,
+ y : int = 0,*/
+ sizing_width : Sizing_Dimension = {.FIT, 0, 0},
+ sizing_height : Sizing_Dimension = {.FIT, 0, 0},
+ layout : Layout = .LEFT_TO_RIGHT,
+ padding : Sides = {0,0,0,0},
+ child_gap : int = 0,
+ color : Color = {1,1,0,1},
+ ) -> ^Tafl{
+
+ parent_ptr : ^Tafl = nil
+ if tafl_stack_depth > 0 {
+ parent_ptr = &tafl_elements[tafl_stack[tafl_stack_depth-1]]
+ }
+
+ tafl_elements[tafl_elements_count] = {
+ /*width = width,
+ height = height,
+ x = x,
+ y = y,*/
+ sizing = {sizing_width, sizing_height},
+ layout = layout,
+ padding = padding,
+ child_gap = child_gap,
+
+ color = color,
+
+ parent = parent_ptr,
+ }
+ this_tafl : ^Tafl = &tafl_elements[tafl_elements_count]
+
+ if this_tafl.sizing.width.type == .FIXED {
+ this_tafl.width = this_tafl.sizing.width.max
+ }
+ if this_tafl.sizing.height.type == .FIXED {
+ this_tafl.height = this_tafl.sizing.height.max
+ }
+
+ tafl_stack[tafl_stack_depth] = tafl_elements_count
+ this_tafl.own_index = tafl_elements_count
+ this_tafl.own_depth = tafl_stack_depth
+ this_tafl.children.index = temp_child_buffer_len
+
+ indent(this_tafl.own_depth)
+ fmt.printfln("┌ Opened tafl {}", this_tafl.own_index)
+
+ tafl_elements_count += 1
+ tafl_stack_depth += 1
+
+ return this_tafl
+}
+
+
+__tafl_close :: proc(tafl : ^Tafl) {
+
+ parent := tafl.parent
+ if parent != nil {
+
+ tafl.width += tafl.padding.left + tafl.padding.right
+ tafl.height += tafl.padding.top + tafl.padding.bottom
+
+ // Not entirely sure yet, because Nic's video doesn't say you need this
+ // max(), but I have a feeling that childless tafls will cause negative
+ // total_child_gaps, which would be bad.
+ //
+ // ALSO: Wtf? Why are we basing this off of the tafls number of siblings?
+ // I do not understand this.
+ total_child_gap := max(tafl.children.len - 1, 0) * tafl.child_gap
+
+ switch parent.layout {
+ case .LEFT_TO_RIGHT:
+ tafl.width += total_child_gap
+ parent.width = min(parent.width+tafl.width, parent.sizing.width.max)
+ parent.height = min(max(tafl.height, parent.height), parent.sizing.height.max)
+ case .TOP_TO_BOTTOM:
+ tafl.height += total_child_gap
+ parent.height = min(parent.height+tafl.height, parent.sizing.height.max)
+ parent.width = min(max(tafl.width, parent.width), parent.sizing.width.max)
+ }
+
+ }
+
+ for i in 0..<tafl.children.len {
+ child_index_buffer[child_index_buffer_len+i] = temp_child_buffer[tafl.children.index+i]
+ temp_child_buffer_len -= 1
+ }
+ tafl.children.index = child_index_buffer_len
+ child_index_buffer_len += tafl.children.len
+
+ temp_child_buffer[temp_child_buffer_len] = tafl.own_index
+ temp_child_buffer_len += 1
+
+ if parent != nil {
+ parent.children.len += 1
+ } else {
+ child_index_buffer[child_index_buffer_len] = 0
+ child_index_buffer_len += 1
+ }
+
+ tafl_stack_depth -= 1
+
+ indent(tafl.own_depth)
+ fmt.printfln("└ Closed tafl {}\t\tchild_buffer:{}\t\ttemp_child_buffer:{}\tchild_index:{} {}", tafl.own_index, child_index_buffer[0:child_index_buffer_len], temp_child_buffer[0:temp_child_buffer_len], tafl.children.index, tafl.children.len)
+}
+
+
+// TODO: Support multiple growing tǫfl
+grow_children :: proc(parent : ^Tafl) {
+
+ // X is the layout direction, Y is across the layout direction.
+ // So that LEFT_TO_RIGHT means X = width,
+ // and TOP_TO_BOTTOM means X = height
+
+ parent_x : ^int
+ parent_y : ^int
+ padding_x : int
+ padding_y : int
+ switch parent.layout {
+ case .LEFT_TO_RIGHT:
+ parent_x = &parent.width
+ parent_y = &parent.height
+ padding_x = parent.padding.left + parent.padding.right
+ padding_y = parent.padding.top + parent.padding.bottom
+ case .TOP_TO_BOTTOM:
+ parent_x = &parent.height
+ parent_y = &parent.width
+ padding_x = parent.padding.top + parent.padding.bottom
+ padding_y = parent.padding.left + parent.padding.right
+ }
+ remaining_x : int = parent_x^
+ remaining_y : int = parent_y^
+ remaining_x -= padding_x
+ remaining_y -= padding_y
+
+ for child in children_of(parent) {
+ switch parent.layout {
+ case .LEFT_TO_RIGHT:
+ remaining_x -= child.width
+ case .TOP_TO_BOTTOM:
+ remaining_x -= child.height
+ }
+ }
+ // Do we need to make sure this isn't negative???
+ remaining_x -= (parent.children.len - 1) * parent.child_gap
+
+ switch parent.layout {
+ case .LEFT_TO_RIGHT:
+ for child in children_of(parent) {
+ if child.sizing.width.type == .GROW {
+ child.width += remaining_x
+ }
+ if child.sizing.height.type == .GROW {
+ child.height += remaining_y - child.height
+ }
+ }
+ case .TOP_TO_BOTTOM:
+ for child in children_of(parent) {
+ if child.sizing.width.type == .GROW {
+ child.width += remaining_y - child.width
+ }
+ if child.sizing.height.type == .GROW {
+ child.height += remaining_x
+ }
+ }
+ }
+}
+
+position_children :: proc(parent: ^Tafl) {
+ switch parent.layout {
+ case .LEFT_TO_RIGHT:
+ left_offset : int = parent.padding.left
+ for child in children_of(parent) {
+ child.x = left_offset
+ child.y = parent.padding.top
+ left_offset += child.width + parent.child_gap
+ }
+ case .TOP_TO_BOTTOM:
+ top_offset : int = parent.padding.top
+ for child in children_of(parent) {
+ child.x = top_offset
+ child.y = parent.padding.left
+ top_offset += child.width + parent.child_gap
+ }
+
+ }
+}
+
+render :: proc() {
+
+ grow_pass()
+ position_pass()
+
+ rl.BeginDrawing()
+ rl.ClearBackground({255,0,0,255})
+
+ #reverse for tafl_index in child_index_buffer[:child_index_buffer_len] {
+ tafl := tafl_elements[tafl_index]
+ color : rl.Color = {u8(tafl.color.r*255.0),
+ u8(tafl.color.g*255.0),
+ u8(tafl.color.b*255.0),
+ u8(tafl.color.a*255.0),}
+ //fmt.printf("%#v\n\n", tafl)
+ rl.DrawRectangleRec({f32(tafl.x), f32(tafl.y), f32(tafl.width), f32(tafl.height),}, color)
+ }
+
+ rl.DrawFPS(5, 5)
+
+ rl.EndDrawing()
+ clear_layout()
+}
+
+grow_pass :: proc() {
+ #reverse for tafl_index in child_index_buffer[:child_index_buffer_len] {
+ tafl := &tafl_elements[tafl_index]
+ grow_children(tafl)
+ }
+}
+
+position_pass :: proc() {
+ #reverse for tafl_index in child_index_buffer[:child_index_buffer_len] {
+ tafl := &tafl_elements[tafl_index]
+ position_children(tafl)
+ }
+}
+
+start_window :: proc(width, height : i32, title : cstring, fps_target : int = 60) {
+ rl.SetWindowMinSize(800,600)
+ rl.SetTargetFPS(60)
+ rl.SetConfigFlags({.WINDOW_RESIZABLE})
+ rl.InitWindow(width, height, title)
+}
+
+window_should_close :: proc() -> bool {
+ return rl.WindowShouldClose()
+}
+
+resized :: proc() -> (resized: bool) {
+ return rl.IsWindowResized()
+}
+
+get_window_size :: proc() -> (i32, i32) {
+ return rl.GetScreenWidth(), rl.GetScreenHeight()
+}
+
+Sizing_Dimension :: struct {
+ type : enum{
+ FIT,
+ GROW,
+ FIXED
+ },
+ min, max : int
+}
+
+Layout :: enum {
+ LEFT_TO_RIGHT,
+ TOP_TO_BOTTOM,
+}
+
+Sides :: struct {
+ top, bottom, left, right : int
+}
+
+Color :: struct {
+ r,g,b,a : f32
+}
+
+Tafl :: struct {
+ width, height : int,
+ x, y : int,
+
+ own_index : int, // Delete me
+ own_depth : int, // Delete me
+
+ parent : ^Tafl,
+ children : struct {
+ index, len : int
+ },
+
+ using style : Tafl_Style,
+}
+
+__child_iterator_index : int = 0
+children_of :: proc(tafl: ^Tafl) -> (child: ^Tafl, ok: bool) {
+ if __child_iterator_index >= tafl.children.len {
+ __child_iterator_index = 0
+ return nil, false
+ }
+
+ // Assuming you have some way to get the actual child at index
+ // This depends on how your children are actually stored
+ child = &tafl_elements[child_index_buffer[(tafl.children.index+__child_iterator_index)]]
+ __child_iterator_index += 1
+ return child, true
+}
+
+Tafl_Style :: struct {
+ sizing : struct {
+ width : Sizing_Dimension,
+ height : Sizing_Dimension,
+ },
+ layout : Layout,
+ padding : Sides,
+ child_gap : int,
+ color : Color,
+}
+
+indent :: proc(x : int) {
+ for _ in 0..<x {
+ fmt.print("│ ")
+ }
+}
+
+GROW : Sizing_Dimension : {.GROW, 0, max(type_of(Sizing_Dimension{}.max))}
+
+FIT : Sizing_Dimension : {.FIT, 0, max(type_of(Sizing_Dimension{}.max))}
+
+FIXED :: proc(x: int) -> Sizing_Dimension {
+ return {.FIXED, x, x}
+}
+
+u8_clamp :: proc(input: f32) -> u8 {
+ mult := input*255
+ output := u8(mult)
+ if mult<0 do output = 0
+ if mult>255 do output = 255
+ return output
+} \ No newline at end of file