From 40687c8c5624dda5bd6b9c6b0e281fb079755040 Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Sat, 26 Aug 2023 12:57:44 +0200 Subject: WIP OUI stuff --- src/ui_implementation.odin | 130 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/ui_implementation.odin (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin new file mode 100644 index 0000000..4842a76 --- /dev/null +++ b/src/ui_implementation.odin @@ -0,0 +1,130 @@ +package main + +import "../lib/oui" +import rl "vendor:raylib" + + + +BGCOLOR : rl.Color : {30, 30, 30, 255} +PBGCOLOR : rl.Color : {40, 40, 40, 255} + +DAY_HEIGHT :: 35 +TIMELINE_START :: 175 +TIMELINE_END :: -85 + + + +Item :: oui.Item +Call :: oui.Call + +Data_Element :: enum int { + Panel, + Button, + Label, + Text_Input, + Timeblock, +// ... +} + +Data_Head :: struct { + subtype: Data_Element, +} + +Data_Panel :: struct { + using _: Data_Head, + color: rl.Color, +} + +Data_Button :: struct { + using _: Data_Head, + text: string, + selected: bool, +} + +Data_Label :: struct { + using _: Data_Head, + text: string, + alignment: Text_Alignment, +} + +button_callback :: proc(item: Item, event: Call) -> int { + data := cast(^Data_Button) oui.get_handle(item) + + #partial switch event { + case .Cursor_Handle: + //return int(Cursor_Type.Hand) + } + + return -1 +} + +panel :: proc(color : rl.Color = rl.RED) -> Item { + item := oui.item_make() + + data := oui.alloc_typed(item, Data_Panel) + data.subtype = .Panel + data.color = color + + return item +} + +button :: proc(text: string, width: int, selected := false) -> Item { + item := oui.item_make() + oui.set_size(item, width, 35) + oui.set_callback(item, button_callback) + + data := oui.alloc_typed(item, Data_Button) + data.subtype = .Button + data.text = text + data.selected = selected + + return item +} + +Text_Alignment :: enum int { + Left, + Right, +} +label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> Item { + item := oui.item_make() + + data := oui.alloc_typed(item, Data_Label) + data.subtype = .Label + data.text = text + data.alignment = alignment + + return item +} + +// recursive loop +ui_draw_children :: proc(item: oui.Item) { + list := oui.children_sorted(item) + for kid in list { + ui_draw(kid) + } +} + +ui_draw :: proc(item: oui.Item) { + head := cast(^Data_Head) oui.get_handle(item) + rect := oui.get_rect(item) + + //fmt.println(rect, head, item) + + if head == nil { + ui_draw_children(item) + return + } + + #partial switch head.subtype { + //case .Panel_Root: + // ... render any type of item + case .Button: + rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), PBGCOLOR) + case .Panel: + subtyped := cast(^Data_Panel) head + rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), subtyped.color) + ui_draw_children(item) + case .Label: + + } +} \ No newline at end of file -- cgit v1.2.1 From e77dec086f94da480af8c42bec6cac8e873a6931 Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Fri, 13 Oct 2023 12:00:49 +0200 Subject: Progressed ability to write text using new oui system --- src/ui_implementation.odin | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index 4842a76..7c5f9e3 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -1,6 +1,8 @@ package main import "../lib/oui" +import "core:strings" +import "core:fmt" import rl "vendor:raylib" @@ -44,6 +46,8 @@ Data_Button :: struct { Data_Label :: struct { using _: Data_Head, text: string, + font: rl.Font, + font_size: i32, alignment: Text_Alignment, } @@ -84,6 +88,7 @@ button :: proc(text: string, width: int, selected := false) -> Item { Text_Alignment :: enum int { Left, Right, + Center } label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> Item { item := oui.item_make() @@ -91,6 +96,7 @@ label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> data := oui.alloc_typed(item, Data_Label) data.subtype = .Label data.text = text + data.font_size = font.baseSize // This should not be necesssary data.alignment = alignment return item @@ -121,10 +127,18 @@ ui_draw :: proc(item: oui.Item) { case .Button: rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), PBGCOLOR) case .Panel: - subtyped := cast(^Data_Panel) head - rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), subtyped.color) + data := cast(^Data_Panel) head + rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), data.color) ui_draw_children(item) case .Label: - + data := cast(^Data_Label) oui.get_handle(item) + + // For some reason, data.font.baseSize == 0 here. It doesn't outside of this function. Dunno why. + font_height := f32(data.font_size) + + rl.DrawTextEx(data.font, strings.unsafe_string_to_cstring(data.text), { 0, 0 }, font_height, 0.0, rl.RAYWHITE); + //rl.DrawTextEx(rl.GetFontDefault(), strings.unsafe_string_to_cstring(data.text), { 0, 0 }, 40, 0, rl.WHITE); + //rl.DrawFPS(0, 0) + //fmt.println(font_height) } } \ No newline at end of file -- cgit v1.2.1 From 0256cea0b389506bc97d1c026d566706e1cc8e76 Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Fri, 13 Oct 2023 18:29:41 +0200 Subject: Fixed font loading in labels --- src/ui_implementation.odin | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index 7c5f9e3..594e5a1 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -88,7 +88,7 @@ button :: proc(text: string, width: int, selected := false) -> Item { Text_Alignment :: enum int { Left, Right, - Center + Center, } label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> Item { item := oui.item_make() @@ -97,6 +97,7 @@ label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> data.subtype = .Label data.text = text data.font_size = font.baseSize // This should not be necesssary + data.font = font data.alignment = alignment return item @@ -135,7 +136,7 @@ ui_draw :: proc(item: oui.Item) { // For some reason, data.font.baseSize == 0 here. It doesn't outside of this function. Dunno why. font_height := f32(data.font_size) - + rl.DrawTextEx(data.font, strings.unsafe_string_to_cstring(data.text), { 0, 0 }, font_height, 0.0, rl.RAYWHITE); //rl.DrawTextEx(rl.GetFontDefault(), strings.unsafe_string_to_cstring(data.text), { 0, 0 }, 40, 0, rl.WHITE); //rl.DrawFPS(0, 0) -- cgit v1.2.1 From a32fc0f0f6bf3acc18e03fb436564cc135717157 Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Fri, 13 Oct 2023 18:33:26 +0200 Subject: Leveraged fix to remove redundancies --- src/ui_implementation.odin | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index 594e5a1..5aa294c 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -96,7 +96,6 @@ label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> data := oui.alloc_typed(item, Data_Label) data.subtype = .Label data.text = text - data.font_size = font.baseSize // This should not be necesssary data.font = font data.alignment = alignment @@ -134,10 +133,7 @@ ui_draw :: proc(item: oui.Item) { case .Label: data := cast(^Data_Label) oui.get_handle(item) - // For some reason, data.font.baseSize == 0 here. It doesn't outside of this function. Dunno why. - font_height := f32(data.font_size) - - rl.DrawTextEx(data.font, strings.unsafe_string_to_cstring(data.text), { 0, 0 }, font_height, 0.0, rl.RAYWHITE); + rl.DrawTextEx(data.font, strings.unsafe_string_to_cstring(data.text), { 0, 0 }, f32(data.font.baseSize), 0.0, rl.RAYWHITE); //rl.DrawTextEx(rl.GetFontDefault(), strings.unsafe_string_to_cstring(data.text), { 0, 0 }, 40, 0, rl.WHITE); //rl.DrawFPS(0, 0) //fmt.println(font_height) -- cgit v1.2.1 From 1197fa1b73bb60dd7bbc67d046e5f8172c3dcfab Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Fri, 13 Oct 2023 19:11:55 +0200 Subject: Added text justification setting --- src/ui_implementation.odin | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index 5aa294c..4706728 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -45,7 +45,7 @@ Data_Button :: struct { Data_Label :: struct { using _: Data_Head, - text: string, + text: cstring, font: rl.Font, font_size: i32, alignment: Text_Alignment, @@ -86,6 +86,7 @@ button :: proc(text: string, width: int, selected := false) -> Item { } Text_Alignment :: enum int { + // Techically called justification, but text_alignment is more self-explanatory. Left, Right, Center, @@ -95,7 +96,7 @@ label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> data := oui.alloc_typed(item, Data_Label) data.subtype = .Label - data.text = text + data.text = strings.unsafe_string_to_cstring(text) data.font = font data.alignment = alignment @@ -132,10 +133,18 @@ ui_draw :: proc(item: oui.Item) { ui_draw_children(item) case .Label: data := cast(^Data_Label) oui.get_handle(item) - - rl.DrawTextEx(data.font, strings.unsafe_string_to_cstring(data.text), { 0, 0 }, f32(data.font.baseSize), 0.0, rl.RAYWHITE); - //rl.DrawTextEx(rl.GetFontDefault(), strings.unsafe_string_to_cstring(data.text), { 0, 0 }, 40, 0, rl.WHITE); - //rl.DrawFPS(0, 0) - //fmt.println(font_height) + + horizontal_position : f32 + + switch data.alignment { + case .Left: + horizontal_position = f32(rect.l) + case .Right: + horizontal_position = f32(rect.l) - rl.MeasureTextEx(data.font, data.text, f32(data.font.baseSize), 0.0).x + case .Center: + horizontal_position = f32(rect.l) - f32(int((rl.MeasureTextEx(data.font, data.text, f32(data.font.baseSize), 0.0).x)/2)) + } + + rl.DrawTextEx(data.font, data.text, { horizontal_position, f32(rect.t+50) }, f32(data.font.baseSize), 0.0, rl.RAYWHITE); } } \ No newline at end of file -- cgit v1.2.1 From d6cb7ac37d86d0c4ee03982813b94275fd62016a Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Sat, 14 Oct 2023 12:18:23 +0200 Subject: Added cute padding to text --- src/ui_implementation.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index 4706728..27bcc65 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -145,6 +145,6 @@ ui_draw :: proc(item: oui.Item) { horizontal_position = f32(rect.l) - f32(int((rl.MeasureTextEx(data.font, data.text, f32(data.font.baseSize), 0.0).x)/2)) } - rl.DrawTextEx(data.font, data.text, { horizontal_position, f32(rect.t+50) }, f32(data.font.baseSize), 0.0, rl.RAYWHITE); + rl.DrawTextEx(data.font, data.text, { horizontal_position, f32(rect.t) }, f32(data.font.baseSize), 0.0, rl.RAYWHITE); } } \ No newline at end of file -- cgit v1.2.1 From fd262c11c3c0f627927ecc7fd5115899033018bb Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Sat, 14 Oct 2023 13:11:39 +0200 Subject: New OUI version --- src/ui_implementation.odin | 59 ++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 20 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index 27bcc65..cf38cc3 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -8,6 +8,7 @@ import rl "vendor:raylib" BGCOLOR : rl.Color : {30, 30, 30, 255} +WBGCOLOR : rl.Color : {20, 25, 25, 255} PBGCOLOR : rl.Color : {40, 40, 40, 255} DAY_HEIGHT :: 35 @@ -51,8 +52,8 @@ Data_Label :: struct { alignment: Text_Alignment, } -button_callback :: proc(item: Item, event: Call) -> int { - data := cast(^Data_Button) oui.get_handle(item) +button_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { + data := cast(^Data_Button) item.handle #partial switch event { case .Cursor_Handle: @@ -62,22 +63,39 @@ button_callback :: proc(item: Item, event: Call) -> int { return -1 } -panel :: proc(color : rl.Color = rl.RED) -> Item { - item := oui.item_make() +panel :: proc(color : rl.Color = rl.RED) -> ^Item { + item := oui.item_make(c0) - data := oui.alloc_typed(item, Data_Panel) + data := oui.alloc_typed(c0, item, Data_Panel) data.subtype = .Panel data.color = color - return item + return item +} + +panel_line :: proc(parent: ^Item, color : rl.Color, height: int = 40) -> (item: ^Item) { + item = oui.item_make(c0) + item.layout_cut_children = .Left + item.layout_size.y = height + + old := parent.layout_cut_children + parent.layout_cut_children = .Top + oui.item_insert(parent, item) + parent.layout_cut_children = old + + data := oui.alloc_typed(c0, item, Data_Panel) + data.subtype = .Panel + data.color = color + + return } -button :: proc(text: string, width: int, selected := false) -> Item { - item := oui.item_make() - oui.set_size(item, width, 35) - oui.set_callback(item, button_callback) +button :: proc(text: string, width: int, selected := false) -> ^Item { + item := oui.item_make(c0) + item.layout_size = {width, 35} + item.callback = button_callback - data := oui.alloc_typed(item, Data_Button) + data := oui.alloc_typed(c0, item, Data_Button) data.subtype = .Button data.text = text data.selected = selected @@ -91,10 +109,10 @@ Text_Alignment :: enum int { Right, Center, } -label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> Item { - item := oui.item_make() +label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> ^Item { + item := oui.item_make(c0) - data := oui.alloc_typed(item, Data_Label) + data := oui.alloc_typed(c0, item, Data_Label) data.subtype = .Label data.text = strings.unsafe_string_to_cstring(text) data.font = font @@ -104,16 +122,17 @@ label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> } // recursive loop -ui_draw_children :: proc(item: oui.Item) { - list := oui.children_sorted(item) +ui_draw_children :: proc(item: ^oui.Item) { + list := oui.children_list(c0, item) + if len(list)>0 do fmt.println(list[len(list)-1]) for kid in list { ui_draw(kid) } } -ui_draw :: proc(item: oui.Item) { - head := cast(^Data_Head) oui.get_handle(item) - rect := oui.get_rect(item) +ui_draw :: proc(item: ^oui.Item) { + head := cast(^Data_Head) item.handle + rect := item.bounds //fmt.println(rect, head, item) @@ -132,7 +151,7 @@ ui_draw :: proc(item: oui.Item) { rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), data.color) ui_draw_children(item) case .Label: - data := cast(^Data_Label) oui.get_handle(item) + data := cast(^Data_Label) item.handle horizontal_position : f32 -- cgit v1.2.1 From fca6955979f4791acb016ef5da86fed1013b524e Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Sat, 14 Oct 2023 14:03:07 +0200 Subject: There are themes! There is button with text! There is increased comfy! --- src/ui_implementation.odin | 71 +++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 20 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index cf38cc3..3e9b913 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -6,10 +6,21 @@ import "core:fmt" import rl "vendor:raylib" +Theme :: struct { + background: rl.Color, + background_top: rl.Color, + background_bottom: rl.Color, + button: rl.Color, + text: rl.Color, +} -BGCOLOR : rl.Color : {30, 30, 30, 255} -WBGCOLOR : rl.Color : {20, 25, 25, 255} -PBGCOLOR : rl.Color : {40, 40, 40, 255} +theme : Theme = { + background = {20, 25, 25, 255}, + background_top = {30, 35, 35, 255}, + background_bottom = {40, 40, 40, 255}, + button = {80, 80, 80, 255}, + text = rl.RAYWHITE, +} DAY_HEIGHT :: 35 TIMELINE_START :: 175 @@ -46,7 +57,7 @@ Data_Button :: struct { Data_Label :: struct { using _: Data_Head, - text: cstring, + text: string, font: rl.Font, font_size: i32, alignment: Text_Alignment, @@ -114,17 +125,39 @@ label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> data := oui.alloc_typed(c0, item, Data_Label) data.subtype = .Label - data.text = strings.unsafe_string_to_cstring(text) + data.text = text data.font = font data.alignment = alignment return item } +calculate_text_alignment :: proc(text: cstring, font: rl.Font, alignment: Text_Alignment, rect: oui.RectI) -> (output: [2]int) { + + measurement := rl.MeasureTextEx(font, text, f32(font.baseSize), 0.0) + + switch alignment { + case .Left: + output.x = rect.l + case .Right: + output.x = rect.r - int(measurement.x) + case .Center: + output.x = (rect.l+(rect.r-rect.l)/2) - int(measurement.x/2) + } + + output.y = (rect.t+(rect.b-rect.t)/2) - int(measurement.y/2) + + return +} +i2f :: proc "contextless" (input: [2]int) -> rl.Vector2 { + return { f32(input.x), f32(input.y) } +} +f2i :: proc "contextless" (input: [2]f32) -> [2]int { + return { int(input.x), int(input.y) } +} // recursive loop ui_draw_children :: proc(item: ^oui.Item) { list := oui.children_list(c0, item) - if len(list)>0 do fmt.println(list[len(list)-1]) for kid in list { ui_draw(kid) } @@ -145,25 +178,23 @@ ui_draw :: proc(item: ^oui.Item) { //case .Panel_Root: // ... render any type of item case .Button: - rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), PBGCOLOR) + data := cast(^Data_Button) item.handle + rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), theme.button) + + text := strings.clone_to_cstring(data.text, context.temp_allocator) + position := calculate_text_alignment(text, font, .Center, rect) + + rl.DrawTextEx(font, text, i2f(position), f32(font.baseSize), 0.0, theme.text); + case .Panel: data := cast(^Data_Panel) head rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), data.color) ui_draw_children(item) case .Label: data := cast(^Data_Label) item.handle - - horizontal_position : f32 - - switch data.alignment { - case .Left: - horizontal_position = f32(rect.l) - case .Right: - horizontal_position = f32(rect.l) - rl.MeasureTextEx(data.font, data.text, f32(data.font.baseSize), 0.0).x - case .Center: - horizontal_position = f32(rect.l) - f32(int((rl.MeasureTextEx(data.font, data.text, f32(data.font.baseSize), 0.0).x)/2)) - } - - rl.DrawTextEx(data.font, data.text, { horizontal_position, f32(rect.t) }, f32(data.font.baseSize), 0.0, rl.RAYWHITE); + text := strings.clone_to_cstring(data.text, context.temp_allocator) + position := calculate_text_alignment(text, data.font, data.alignment, rect) + + rl.DrawTextEx(data.font, text, i2f(position), f32(data.font.baseSize), 0.0, theme.text); } } \ No newline at end of file -- cgit v1.2.1 From 44d408583ab8811f2b89d8fcb9e21b98f1409b7d Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Sat, 14 Oct 2023 16:19:16 +0200 Subject: There is a theme editor now??? --- src/ui_implementation.odin | 139 +++++++++++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 37 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index 3e9b913..6b0947d 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -8,32 +8,43 @@ import rl "vendor:raylib" Theme :: struct { background: rl.Color, - background_top: rl.Color, - background_bottom: rl.Color, + background_bar: rl.Color, button: rl.Color, + base: rl.Color, + slider_bar: rl.Color, text: rl.Color, } -theme : Theme = { +/*theme : Theme = { background = {20, 25, 25, 255}, background_top = {30, 35, 35, 255}, background_bottom = {40, 40, 40, 255}, button = {80, 80, 80, 255}, + base = {60, 60, 60, 255}, + slider_bar = {170, 170, 170, 255}, text = rl.RAYWHITE, +}*/ + +theme : Theme = { + background = {25 , 27 , 29 , 255,}, + background_bar = {43 , 43 , 48 , 255,}, + button = {91 , 91 , 204, 255,}, + base = {60 , 60 , 60 , 255,}, + slider_bar = {91 , 91 , 204, 255,}, + text = {255, 255, 255, 252,}, } DAY_HEIGHT :: 35 TIMELINE_START :: 175 TIMELINE_END :: -85 - - Item :: oui.Item Call :: oui.Call Data_Element :: enum int { Panel, Button, + Slider, Label, Text_Input, Timeblock, @@ -55,6 +66,12 @@ Data_Button :: struct { selected: bool, } +Data_Slider :: struct { + using _: Data_Head, + text: string, + value: ^u8, +} + Data_Label :: struct { using _: Data_Head, text: string, @@ -63,17 +80,6 @@ Data_Label :: struct { alignment: Text_Alignment, } -button_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { - data := cast(^Data_Button) item.handle - - #partial switch event { - case .Cursor_Handle: - //return int(Cursor_Type.Hand) - } - - return -1 -} - panel :: proc(color : rl.Color = rl.RED) -> ^Item { item := oui.item_make(c0) @@ -105,6 +111,7 @@ button :: proc(text: string, width: int, selected := false) -> ^Item { item := oui.item_make(c0) item.layout_size = {width, 35} item.callback = button_callback + item.id = oui.gen_id(c0, text) data := oui.alloc_typed(c0, item, Data_Button) data.subtype = .Button @@ -113,6 +120,50 @@ button :: proc(text: string, width: int, selected := false) -> ^Item { return item } +button_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { + data := cast(^Data_Button) item.handle + + #partial switch event { + case .Cursor_Handle: + //return int(Cursor_Type.Hand) + } + + return -1 +} + +slider :: proc(id: string, text: string, width: int, value: ^u8) -> ^Item { + item := oui.item_make(c0) + item.layout_size = {width, 25} + item.id = oui.gen_id(c0, id) + item.callback = slider_callback + + data := oui.alloc_typed(c0, item, Data_Slider) + data.subtype = .Slider + data.text = text + data.value = value + + return item +} +slider_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { + data := cast(^Data_Slider) item.handle + rect := item.bounds + + #partial switch event { + case .Left_Capture: + cursor_position := clamp(oui.get_cursor(c0).x, rect.l, rect.r) + + data.value^ = u8(255*(f32(cursor_position - rect.l) / f32(rect.r - rect.l))) + } + + return -1 +} +color_sliders :: proc(parent: ^Item, color: ^rl.Color) { + width :: 167 + oui.item_insert(parent, slider("slider_r", fmt.tprintf("%d", color.r), width, &color.r)) + oui.item_insert(parent, slider("slider_g", fmt.tprintf("%d", color.g), width, &color.g)) + oui.item_insert(parent, slider("slider_b", fmt.tprintf("%d", color.b), width, &color.b)) + oui.item_insert(parent, slider("slider_a", fmt.tprintf("%d", color.a), width, &color.a)) +} Text_Alignment :: enum int { // Techically called justification, but text_alignment is more self-explanatory. @@ -122,6 +173,7 @@ Text_Alignment :: enum int { } label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> ^Item { item := oui.item_make(c0) + item.layout_size = {150, 25} data := oui.alloc_typed(c0, item, Data_Label) data.subtype = .Label @@ -175,26 +227,39 @@ ui_draw :: proc(item: ^oui.Item) { } #partial switch head.subtype { - //case .Panel_Root: - // ... render any type of item - case .Button: - data := cast(^Data_Button) item.handle - rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), theme.button) - - text := strings.clone_to_cstring(data.text, context.temp_allocator) - position := calculate_text_alignment(text, font, .Center, rect) - - rl.DrawTextEx(font, text, i2f(position), f32(font.baseSize), 0.0, theme.text); - - case .Panel: - data := cast(^Data_Panel) head - rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), data.color) - ui_draw_children(item) - case .Label: - data := cast(^Data_Label) item.handle - text := strings.clone_to_cstring(data.text, context.temp_allocator) - position := calculate_text_alignment(text, data.font, data.alignment, rect) - - rl.DrawTextEx(data.font, text, i2f(position), f32(data.font.baseSize), 0.0, theme.text); + //case .Panel_Root: + // ... render any type of item + case .Button: + data := cast(^Data_Button) item.handle + rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), theme.button) + + text := strings.clone_to_cstring(data.text, context.temp_allocator) + position := calculate_text_alignment(text, font, .Center, rect) + + rl.DrawTextEx(font, text, i2f(position), f32(font.baseSize), 0.0, theme.text); + + //fmt.println(item.anim) + + case .Slider: + data := cast(^Data_Slider) head + rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), theme.base) + rl.DrawRectangle(i32(rect.l+1), i32(rect.t+1), i32(f32(rect.r-rect.l)*(f32(data.value^)/255)-2), i32(rect.b-rect.t-2), theme.slider_bar) + + text := strings.clone_to_cstring(data.text, context.temp_allocator) + position := calculate_text_alignment(text, font, .Center, rect) + + rl.DrawTextEx(font, text, i2f(position), f32(font.baseSize), 0.0, theme.text); + + case .Panel: + data := cast(^Data_Panel) head + rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), data.color) + ui_draw_children(item) + + case .Label: + data := cast(^Data_Label) item.handle + text := strings.clone_to_cstring(data.text, context.temp_allocator) + position := calculate_text_alignment(text, data.font, data.alignment, rect) + + rl.DrawTextEx(data.font, text, i2f(position), f32(data.font.baseSize), 0.0, theme.text); } } \ No newline at end of file -- cgit v1.2.1 From a437a92bb39894beb91d6c4308d04852bc0d5eac Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Sat, 14 Oct 2023 17:05:01 +0200 Subject: Advancements on theme and layout --- src/ui_implementation.odin | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index 6b0947d..e4b4f80 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -13,18 +13,12 @@ Theme :: struct { base: rl.Color, slider_bar: rl.Color, text: rl.Color, + price_100: rl.Color, + price_150: rl.Color, + price_200: rl.Color, + price_300: rl.Color, } -/*theme : Theme = { - background = {20, 25, 25, 255}, - background_top = {30, 35, 35, 255}, - background_bottom = {40, 40, 40, 255}, - button = {80, 80, 80, 255}, - base = {60, 60, 60, 255}, - slider_bar = {170, 170, 170, 255}, - text = rl.RAYWHITE, -}*/ - theme : Theme = { background = {25 , 27 , 29 , 255,}, background_bar = {43 , 43 , 48 , 255,}, @@ -32,6 +26,10 @@ theme : Theme = { base = {60 , 60 , 60 , 255,}, slider_bar = {91 , 91 , 204, 255,}, text = {255, 255, 255, 252,}, + price_100 = {30 , 240, 30 , 255,}, + price_150 = {240, 200, 30 , 255,}, + price_200 = {240, 30 , 30 , 255,}, + price_300 = {240, 30 , 240, 255,}, } DAY_HEIGHT :: 35 @@ -171,9 +169,9 @@ Text_Alignment :: enum int { Right, Center, } -label :: proc(text: string, font: rl.Font, alignment: Text_Alignment = .Left) -> ^Item { +label :: proc(text: string, font: rl.Font, width: int = 150, alignment: Text_Alignment = .Left) -> ^Item { item := oui.item_make(c0) - item.layout_size = {150, 25} + item.layout_size = {width, 25} data := oui.alloc_typed(c0, item, Data_Label) data.subtype = .Label -- cgit v1.2.1 From 2e3a7e10756954dc5a99d617a1c0eef327d3adbb Mon Sep 17 00:00:00 2001 From: San Jacobs Date: Sun, 15 Oct 2023 14:37:29 +0200 Subject: Normalized timelines and editor for spacing and sizing --- src/ui_implementation.odin | 168 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 147 insertions(+), 21 deletions(-) (limited to 'src/ui_implementation.odin') diff --git a/src/ui_implementation.odin b/src/ui_implementation.odin index e4b4f80..6839b57 100644 --- a/src/ui_implementation.odin +++ b/src/ui_implementation.odin @@ -10,6 +10,8 @@ Theme :: struct { background: rl.Color, background_bar: rl.Color, button: rl.Color, + button_hover: rl.Color, + button_click: rl.Color, base: rl.Color, slider_bar: rl.Color, text: rl.Color, @@ -23,6 +25,8 @@ theme : Theme = { background = {25 , 27 , 29 , 255,}, background_bar = {43 , 43 , 48 , 255,}, button = {91 , 91 , 204, 255,}, + button_hover = {91 , 91 , 204, 255,}, + button_click = {91 , 91 , 204, 255,}, base = {60 , 60 , 60 , 255,}, slider_bar = {91 , 91 , 204, 255,}, text = {255, 255, 255, 252,}, @@ -32,9 +36,28 @@ theme : Theme = { price_300 = {240, 30 , 240, 255,}, } -DAY_HEIGHT :: 35 -TIMELINE_START :: 175 -TIMELINE_END :: -85 +Sizings :: struct { + date: int, + call: int, + wrap: int, + price: int, + lunch: int, + timeline: int, + inter_timeline: int, +} +sizings : Sizings = { + date = 110, + call = 85, + wrap = 90, + price = 100, + lunch = 100, + timeline = 32, + inter_timeline = 5, +} + +DAY_HEIGHT :: 35 // Only here for legacy UI +TIMELINE_START :: 175 // Only here for legacy UI +TIMELINE_END :: -85 // Only here for legacy UI Item :: oui.Item Call :: oui.Call @@ -42,10 +65,12 @@ Call :: oui.Call Data_Element :: enum int { Panel, Button, - Slider, + SliderU8, + SliderInt, Label, Text_Input, Timeblock, + Timeline, // ... } @@ -64,7 +89,15 @@ Data_Button :: struct { selected: bool, } -Data_Slider :: struct { +Data_SliderInt :: struct { + using _: Data_Head, + text: string, + value: ^int, + min: int, + max: int, +} + +Data_SliderU8 :: struct { using _: Data_Head, text: string, value: ^u8, @@ -78,6 +111,11 @@ Data_Label :: struct { alignment: Text_Alignment, } +Data_Timeline :: struct { + using _: Data_Head, + day: ^Workday, +} + panel :: proc(color : rl.Color = rl.RED) -> ^Item { item := oui.item_make(c0) @@ -129,21 +167,50 @@ button_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { return -1 } -slider :: proc(id: string, text: string, width: int, value: ^u8) -> ^Item { +slider_int :: proc(id: string, text: string, width: int, value: ^int, min: int, max: int) -> ^Item { + item := oui.item_make(c0) + item.layout_size = {width, 25} + item.id = oui.gen_id(c0, id) + item.callback = slider_int_callback + + data := oui.alloc_typed(c0, item, Data_SliderInt) + data.subtype = .SliderInt + data.text = text + data.value = value + data.min = min + data.max = max + + return item +} +slider_int_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { + data := cast(^Data_SliderInt) item.handle + rect := item.bounds + + #partial switch event { + case .Left_Capture: + cursor_position := clamp(oui.get_cursor(c0).x, rect.l, rect.r) + + data.value^ = int(f32(data.min) + (f32(data.max - data.min) * (f32(cursor_position - rect.l) / f32(rect.r - rect.l)))) + } + + return -1 +} + +slider_u8 :: proc(id: string, text: string, width: int, value: ^u8) -> ^Item { item := oui.item_make(c0) item.layout_size = {width, 25} item.id = oui.gen_id(c0, id) - item.callback = slider_callback + item.callback = slider_u8_callback - data := oui.alloc_typed(c0, item, Data_Slider) - data.subtype = .Slider + data := oui.alloc_typed(c0, item, Data_SliderU8) + data.subtype = .SliderU8 data.text = text data.value = value return item } -slider_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { - data := cast(^Data_Slider) item.handle +slider_u8_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { + data := cast(^Data_SliderU8) item.handle rect := item.bounds #partial switch event { @@ -157,10 +224,21 @@ slider_callback :: proc(ctxt: ^oui.Context, item: ^Item, event: Call) -> int { } color_sliders :: proc(parent: ^Item, color: ^rl.Color) { width :: 167 - oui.item_insert(parent, slider("slider_r", fmt.tprintf("%d", color.r), width, &color.r)) - oui.item_insert(parent, slider("slider_g", fmt.tprintf("%d", color.g), width, &color.g)) - oui.item_insert(parent, slider("slider_b", fmt.tprintf("%d", color.b), width, &color.b)) - oui.item_insert(parent, slider("slider_a", fmt.tprintf("%d", color.a), width, &color.a)) + oui.item_insert(parent, slider_u8("slider_r", fmt.tprintf("%d", color.r), width, &color.r)) + oui.item_insert(parent, slider_u8("slider_g", fmt.tprintf("%d", color.g), width, &color.g)) + oui.item_insert(parent, slider_u8("slider_b", fmt.tprintf("%d", color.b), width, &color.b)) + oui.item_insert(parent, slider_u8("slider_a", fmt.tprintf("%d", color.a), width, &color.a)) +} + +timeline :: proc(parent: ^Item, day: ^Workday) -> ^Item { + item := oui.item_make(c0) + + data := oui.alloc_typed(c0, item, Data_Timeline) + data.subtype = .Timeline + data.day = day + + oui.item_insert(parent, item) + return item } Text_Alignment :: enum int { @@ -181,9 +259,9 @@ label :: proc(text: string, font: rl.Font, width: int = 150, alignment: Text_Ali return item } -calculate_text_alignment :: proc(text: cstring, font: rl.Font, alignment: Text_Alignment, rect: oui.RectI) -> (output: [2]int) { +calculate_text_alignment :: proc(text: cstring, font: rl.Font, alignment: Text_Alignment, rect: oui.RectI, spacing: f32 = 0) -> (output: [2]int) { - measurement := rl.MeasureTextEx(font, text, f32(font.baseSize), 0.0) + measurement := rl.MeasureTextEx(font, text, f32(font.baseSize), spacing) switch alignment { case .Left: @@ -229,17 +307,28 @@ ui_draw :: proc(item: ^oui.Item) { // ... render any type of item case .Button: data := cast(^Data_Button) item.handle + text_spacing := clamp(item.anim.hot - item.anim.active, 0, item.anim.hot)*2 rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), theme.button) text := strings.clone_to_cstring(data.text, context.temp_allocator) - position := calculate_text_alignment(text, font, .Center, rect) + position := calculate_text_alignment(text, font, .Center, rect, text_spacing) - rl.DrawTextEx(font, text, i2f(position), f32(font.baseSize), 0.0, theme.text); + rl.DrawTextEx(font, text, i2f(position), f32(font.baseSize), text_spacing, theme.text); //fmt.println(item.anim) - case .Slider: - data := cast(^Data_Slider) head + case .SliderInt: + data := cast(^Data_SliderInt) head + rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), theme.base) + rl.DrawRectangle(i32(rect.l+1), i32(rect.t+1), i32(f32(rect.r-rect.l)*(f32(data.value^)/f32(data.max))-2), i32(rect.b-rect.t-2), theme.slider_bar) + + text := strings.clone_to_cstring(data.text, context.temp_allocator) + position := calculate_text_alignment(text, font, .Center, rect) + + rl.DrawTextEx(font, text, i2f(position), f32(font.baseSize), 0.0, theme.text); + + case .SliderU8: + data := cast(^Data_SliderU8) head rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), theme.base) rl.DrawRectangle(i32(rect.l+1), i32(rect.t+1), i32(f32(rect.r-rect.l)*(f32(data.value^)/255)-2), i32(rect.b-rect.t-2), theme.slider_bar) @@ -259,5 +348,42 @@ ui_draw :: proc(item: ^oui.Item) { position := calculate_text_alignment(text, data.font, data.alignment, rect) rl.DrawTextEx(data.font, text, i2f(position), f32(data.font.baseSize), 0.0, theme.text); + + case .Timeline: + data := cast(^Data_Timeline) item.handle + + width := int(f32(rect.r - rect.l)/(FRACT_MAX - FRACT_MIN)) + + for fracts, i in data.day.fractions { + + color := theme.price_100 + value := data.day.blocks[i].value + + switch { + case value>2.1: + color = theme.price_300 + case value>1.6: + color = theme.price_200 + case value>1.1: + color = theme.price_150 + } + + + + rl.DrawRectangle(i32(rect.l + int(f32(width)*fracts.start) - int(f32(width)*FRACT_MIN)), + i32(rect.t), + i32(f32(width) * (fracts.end - fracts.start)+0.99), + i32(rect.b - rect.t), + color) + // Dark middle of blocks, glowing edge. Disabled for now. + /*rl.DrawRectangle(i32(rect.l + int(f32(width)*fracts.start) - int(f32(width)*FRACT_MIN) + 1), + i32(rect.t) + 1, + i32(f32(width+1) * (fracts.end - fracts.start)-1.01), + i32(rect.b - rect.t)-2, + {0,0,0,100})*/ + if i+1 == data.day.total_timeblocks { + break + } + } } } \ No newline at end of file -- cgit v1.2.1