package main import rl "libraries/raylib" import "base:runtime" import "core:fmt" WINDOW_WIDTH :: 1280 WINDOW_HEIGHT :: 720 WINDOW_FRAMERATE :: 30 WINDOW_CAPTION :: "Transformation Visualizer" MATRIX_FIELD_COUNT :: 1024 MATRIX_FIELD_BYTES :: 8 program: Program Program :: struct { ui_state: UiState, matrices: [dynamic; MATRIX_FIELD_COUNT]f32, matrix_fields: [dynamic; MATRIX_FIELD_COUNT][MATRIX_FIELD_BYTES]byte, matrix_type: MatrixType, } MatrixType :: enum { Mat2, Mat3, Mat4, } @rodata matrix_type_table := [MatrixType]typeid { .Mat2 = mat2, .Mat3 = mat3, .Mat4 = mat4, } init :: proc() { rl.SetTraceLogLevel(.WARNING) rl.SetConfigFlags({.WINDOW_RESIZABLE, .VSYNC_HINT}) rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_CAPTION) rl.SetTargetFPS(WINDOW_FRAMERATE) ui_style := UiStyle{ margin = 4.0, padding = 4.0, font = rl.GetFontDefault(), font_size = 16.0, font_sep = 1.0 } ui_init(&program.ui_state, ui_style, {0, 0}, context.temp_allocator) } matrix_add :: proc() { matrices := &program.matrices append(matrices, 1) append(matrices, 0) append(matrices, 1) append(matrices, 0) fields := &program.matrix_fields append(fields, [MATRIX_FIELD_BYTES]byte{}) append(fields, [MATRIX_FIELD_BYTES]byte{}) append(fields, [MATRIX_FIELD_BYTES]byte{}) append(fields, [MATRIX_FIELD_BYTES]byte{}) } update :: proc() { if rl.IsMouseButtonPressed(.LEFT) { ui_element_focus_reset(&program.ui_state) } rl.BeginDrawing() defer rl.EndDrawing() rl.ClearBackground(rl.BLACK) ui_button_size_top_bar := v2{32.0, 32.0} ui_start(&program.ui_state) ui_container_begin({label = ""}) ui_button(ui_button_size_top_bar, {label = "#10#", callback = matrix_add}) ui_same_line() ui_button(ui_button_size_top_bar, {label = "#11#"}) ui_same_line() ui_button(ui_button_size_top_bar, {label = "#12#"}) ui_container_end() ui_container_begin({label = "Matrices"}) if len(program.matrices) == 0 { ui_text({text = "Add matrices", color = rl.WHITE}) } else { ui_input_size_matrix := v2{48.0, 32.0} switch program.matrix_type { case .Mat2: mat := cast(^mat2)&program.matrices[0] fields := &program.matrix_fields ui_input(ui_input_size_matrix, {label = "", min = 0, max = 1000, input = fields[0][:]}) ui_same_line() ui_input(ui_input_size_matrix, {label = "", min = 0, max = 1000, input = fields[1][:]}) ui_input(ui_input_size_matrix, {label = "", min = 0, max = 1000, input = fields[2][:]}) ui_same_line() ui_input(ui_input_size_matrix, {label = "", min = 0, max = 1000, input = fields[3][:]}) case .Mat3, .Mat4: } } ui_container_end() ui_elements := ui_end() for element in ui_elements { switch element.type { case .Button: data := element.data.(UiElementData_Button) if rl.GuiButton(element.area, data.label) && data.callback != nil { data.callback() } case .Input: data := element.data.(UiElementData_Input) edit_mode := ui_element_is_editing(program.ui_state, element.id) input_cstr := cstring(raw_data(data.input)) if (rl.GuiTextBox(element.area, input_cstr, i32(len(data.input) - 1), edit_mode)) { ui_element_focus(&program.ui_state, element.id) fmt.println("oentuh") } case .Container: data := element.data.(UiElementData_Container) if len(data.label) == 0 { rl.DrawRectangleRoundedLinesEx(element.area, 0.1, 2, 1.0, rl.WHITE) } else { rl.GuiGroupBox(element.area, data.label) } case .Text: data := element.data.(UiElementData_Text) style := program.ui_state.style rl.DrawTextEx(style.font, data.text, rect_get_tl(element.area), style.font_size, style.font_sep, data.color) } } free_all(context.temp_allocator) } parent_window_size_changed :: proc(w, h: int) { rl.SetWindowSize(i32(w), i32(h)) } shutdown :: proc() { rl.CloseWindow() } should_run :: proc() -> bool { when ODIN_OS != .JS { if rl.WindowShouldClose() { return false } } return true }