package main import "../lib/oui" import "core:strings" import "core:fmt" import rl "vendor:raylib" Theme :: struct { background: rl.Color, background_bar: rl.Color, button: rl.Color, base: rl.Color, slider_bar: rl.Color, text: 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,}, 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, // ... } 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_Slider :: struct { using _: Data_Head, text: string, value: ^u8, } Data_Label :: struct { using _: Data_Head, text: string, font: rl.Font, font_size: i32, alignment: Text_Alignment, } panel :: proc(color : rl.Color = rl.RED) -> ^Item { item := oui.item_make(c0) data := oui.alloc_typed(c0, item, Data_Panel) data.subtype = .Panel data.color = color 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(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 data.text = text data.selected = selected 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. Left, Right, Center, } 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 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) for kid in list { ui_draw(kid) } } ui_draw :: proc(item: ^oui.Item) { head := cast(^Data_Head) item.handle rect := item.bounds //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: 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); } }