package main import "../lib/oui" import "core:fmt" import "core:math" import "core:slice" import "core:strings" import rl "vendor:raylib" main :: proc() { // TODO: Replace the dynamic array of Workday-pointers with // an actual array of Workdays, plus a length variable // for cache reasons, and to simplify the process of // adding new Workdays to the array. workdays: [dynamic]^Workday resize(&workdays, 3) workday0: = new_workday({10, 22, 3, 5, 2023}, {00, 08, 4, 5, 2023}, {00, 22, 4, 5, 2023}, {30, 21, 4, 5, 2023}) workdays[0] = &workday0 workday1: = new_workday(workday0.wrap, {00, 08, 5, 5, 2023}, {30, 15, 5, 5, 2023}, {30, 16, 5, 5, 2023}) workdays[1] = &workday1 workday2: = new_workday(workday1.wrap, {00, 12, 6, 5, 2023}, {15, 17, 6, 5, 2023}, {00, 17, 6, 5, 2023}) workdays[2] = &workday2 slice.sort_by(workdays[:], lessWorkdayPtr) //call_text: cstring = "00:00" call_text: = make([]byte, 6) defer delete(call_text) call_text[len(call_text)-1] = 0 //wrap_text: cstring = "00:00" wrap_text: = make([]byte, 6) defer delete(wrap_text) wrap_text[len(wrap_text)-1] = 0 date_text: = make([]byte, len(toString(workday0.call))+1 ) defer delete(date_text) wrap_text[len(wrap_text)-1] = 0 total_sum: cstring = "3500 NOK + 26%" inc_soc: cstring = "4276 NOK" text_height: f32 using rl width: i32 = 700 height: i32 = 400 InitWindow(width, height, "satscalc") defer CloseWindow() SetTargetFPS(60) SetWindowState({.WINDOW_RESIZABLE}) SetWindowMinSize(width, height) // Loading fonts - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - font_size :: 18 font: Font = LoadFontEx("res/UbuntuMono-Regular.ttf", font_size, nil, 0) defer UnloadFont(font) small_font_size :: 14 small_font: Font = LoadFontEx("res/UbuntuMono-Regular.ttf", small_font_size, nil, 0) defer UnloadFont(small_font) big_font_size :: 24 big_font: Font = LoadFontEx("res/UbuntuMono-Regular.ttf", big_font_size, nil, 0) defer UnloadFont(big_font) // oui stuff c0 := oui.context_create(1028, 1028 * 8) defer oui.context_destroy(c0) oui.context_make_current(c0) // Setting up the timelines for day in workdays { beginning: Moment = {0, 0, day.call.day, day.call.month, day.call.year} fmt.println("\nNew day!") for each_block, i in day.blocks { if i == day.total_timeblocks do break day.fractions[i].start = daycount(diff(beginning, each_block.start)) day.fractions[i].end = daycount(diff(beginning, each_block.end)) fmt.println(day.fractions[i]) } } for !WindowShouldClose() { // MAIN LOOP ---- MAIN LOOP ---- MAIN LOOP ---- MAIN LOOP if IsWindowResized() { height = GetScreenHeight() width = GetScreenWidth() fmt.println("Resized to:", width, 'x', height) } // TODO: Find a good way to calculate the size and location // of all the timeblocks in every day. // // I know I want them to scale with the window, and // that the width of them should be normalized. // If you add a day that lasts until 4 AM the morning // after, all the other days should scale down to keep // the vertical alignment of time accurate // // TODO: Hovering over a timeblock should make it pulse softly // clicking will put a white border around the timeblock, // and display information about the block in the // bottom left of the screen. mousePosition: = rl.GetMousePosition() oui.set_cursor(int(mousePosition.x), int(mousePosition.y)) oui.set_button(.Left, rl.IsMouseButtonPressed(rl.MouseButton(0))) // DRAW // ------------------------------------------ BeginDrawing() ClearBackground(BGCOLOR) // hotloop oui.begin_layout() a_panel := panel() oui.set_layout(a_panel, .Absolute) oui.set_size(a_panel, 200, 200) oui.set_offset(a_panel, 20, 20) a_button := button("Testerino", 50) if oui.latest_clicked() { fmt.println("CLICKO BOIO") } oui.set_cut(a_panel, .Left) oui.set_height(a_button, 50) oui.set_offset(a_button, 20, 20) oui.item_insert(a_panel, a_button) oui.end_layout() ui_draw(0) // DRAW HERE OR BELOW oui.process() /* DrawTextEx(font, "Date", {20, 8}, font_size, 0, RAYWHITE); DrawTextEx(font, "Calltime", {105, 8}, font_size, 0, RAYWHITE); DrawTextEx(font, "Wraptime", {f32(width)-83, 8}, font_size, 0, RAYWHITE); for day, i in workdays { // TODO: The fractions held inside Workday-s needs to come in pairs, // just like moments come as pairs in timeblocks. // Because that will let us store both the beginning and ending // of timeblocks, which is a simple way to take care of reading // out-of-bounds and will make it possible to render lunch breaks // // (At least, given how lunch breaks are currently implemented, // as holes in the workday) DrawRectangle(10, DAY_HEIGHT*i32(i+1)-4, width-20, DAY_HEIGHT-1, PBGCOLOR) for block, j in day.blocks { if j == day.total_timeblocks do break block_color: = GREEN switch { case block.value > 2.1: block_color = PURPLE case block.value > 1.6: block_color = RED case block.value > 1.1: block_color = ORANGE } DrawRectangle(TIMELINE_START+i32(math.round(day.fractions[j].start*f32(width+TIMELINE_END-TIMELINE_START))), DAY_HEIGHT*i32(i+1)-4, i32(math.round(f32(width+TIMELINE_END-TIMELINE_START)*(day.fractions[j].end-day.fractions[j].start)+0.5)), DAY_HEIGHT-1, block_color) } copy(call_text, clockprint(day.call)) copy(wrap_text, clockprint(day.wrap)) copy(date_text, toString(day.call)) text_height = math.round(f32(i+1)*DAY_HEIGHT+(DAY_HEIGHT-font_size)*0.25) DrawTextEx(font, cstring(&date_text[0]), {20, text_height}, font_size, 0, RAYWHITE); DrawTextEx(font, cstring(&wrap_text[0]), {f32(width)-70, text_height}, font_size, 0, RAYWHITE); if i == len(workdays)-1 { DrawTextEx(big_font, "+", {20, DAY_HEIGHT*f32(i+2)}, big_font_size, 0, RAYWHITE) } } DrawRectangle(0, height-50, width+10, 60, PBGCOLOR) DrawTextEx(small_font, total_sum, {f32(width)-120, f32(height)-43}, small_font_size, 0, RAYWHITE); DrawTextEx(big_font, inc_soc, {f32(width)-120, f32(height)-29}, big_font_size, 0, RAYWHITE); */ EndDrawing() } } 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, Text_Input, Timeblock, // ... } Data_Head :: struct { subtype: Data_Element, } Data_Panel :: struct { using _: Data_Head, } Data_Button :: struct { using _: Data_Head, text: string, selected: bool, } 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() -> Item { item := oui.item_make() data := oui.alloc_typed(item, Data_Panel) data.subtype = .Panel 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 } // 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: rl.DrawRectangle(i32(rect.l), i32(rect.t), i32(rect.r-rect.l), i32(rect.b-rect.t), rl.RED) ui_draw_children(item) } }