From 4839adf6c1f1783cf7b612bd3fa8dfb0db463c8f Mon Sep 17 00:00:00 2001 From: Jason Hilder Date: Fri, 12 Jun 2026 09:44:24 +0200 Subject: [PATCH] Initial workings for components. --- src/simulator/left_panel.odin | 108 ++++++++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/src/simulator/left_panel.odin b/src/simulator/left_panel.odin index 39fc054..26abbb2 100644 --- a/src/simulator/left_panel.odin +++ b/src/simulator/left_panel.odin @@ -5,6 +5,7 @@ import "core:strings" import rl "vendor:raylib" gui_left_panel :: proc(rect: rl.Rectangle, sim: ^Simulator) { + // ── Top panel and components ── top_panel := rl.Rectangle { rect.x, rect.y, @@ -12,8 +13,18 @@ gui_left_panel :: proc(rect: rl.Rectangle, sim: ^Simulator) { rect.height / 2, } rl.DrawRectangleLinesEx(top_panel, 1, rl.DARKGRAY) - gui_file_loader(top_panel) + // Dropzone/file loader + file_loader_rect := rl.Rectangle { + top_panel.x + PANEL_PADDING, + top_panel.y + PANEL_HEADER, + top_panel.width - PANEL_PADDING * 2, + (top_panel.height / 3) - PANEL_HEADER - PANEL_PADDING * 2, + } + rl.GuiPanel(file_loader_rect, "Rom / File") + gui_file_loader(file_loader_rect) + + // ── Bottom panel and components ── bottom_panel := rl.Rectangle { rect.x, rect.y + top_panel.height, @@ -24,49 +35,98 @@ gui_left_panel :: proc(rect: rl.Rectangle, sim: ^Simulator) { gui_key_pad(bottom_panel, sim.machine.keypad, sim.font) } -gui_file_loader :: proc(rect: rl.Rectangle,) { +gui_file_loader :: proc(rect: rl.Rectangle) { + // drop-zone occupies the panel's content area, minus space for the button + drop_zone := rl.Rectangle { + rect.x + PANEL_PADDING, + rect.y + PANEL_HEADER + PANEL_PADDING, + rect.width - PANEL_PADDING * 2, + rect.height - PANEL_HEADER - PANEL_PADDING * 2 - BUTTON_HEIGHT - PANEL_PADDING, + } + rl.DrawRectangleLinesEx(drop_zone, 1, rl.GREEN) + + // centered drop-zone text + text: cstring = "Drop a CHIP-8 ROM here" + text_width := rl.MeasureText(text, DROP_FONT_SIZE) + text_x := drop_zone.x + (drop_zone.width - f32(text_width)) / 2 + text_y := drop_zone.y + (drop_zone.height - f32(DROP_FONT_SIZE)) / 2 + rl.DrawText(text, i32(text_x), i32(text_y), DROP_FONT_SIZE, rl.GRAY) + + // open rom button below drop-zone + btn_rect := rl.Rectangle { + drop_zone.x, + drop_zone.y + drop_zone.height + PANEL_PADDING, + BUTTON_WIDTH, + BUTTON_HEIGHT, + } + + if rl.GuiButton(btn_rect, "Open ROM") { + // @TODO: get tinyfiledialog working here + } + + // Handle file drop if rl.IsFileDropped() { - log.info("file drop found!") dropped_file := rl.LoadDroppedFiles() + if dropped_file.count > 0 { + mouse := rl.GetMousePosition() - if dropped_file.count > 1 { - path_str := string(dropped_file.paths[0]) - log.info("file dropped: ", path_str) + if rl.CheckCollisionPointRec(mouse, drop_zone) { + path_str := string(dropped_file.paths[0]) + log.info("file dropped: ", path_str) + // @TODO: Stop sim, reset mem etc, load new rom + } else { + log.info("File dropped outside drop zone, ignoring") + } } - rl.UnloadDroppedFiles(dropped_file) } } -gui_key_pad :: proc(rect: rl.Rectangle, display: [16]bool, font: rl.Font) { - Key :: struct { label: string, index: int} +gui_key_pad :: proc(rect: rl.Rectangle, display: [16]bool, font: rl.Font) { + rl.GuiPanel(rect, "Input / Keypad") + + content := rl.Rectangle { + rect.x + PANEL_PADDING, + rect.y + PANEL_HEADER + PANEL_PADDING, + rect.width - PANEL_PADDING * 2, + rect.height - PANEL_HEADER - PANEL_PADDING * 2, + } + + Key :: struct { + label: string, + index: int, + } keys := [16]Key { {"1", 1}, {"2", 2}, {"3", 3}, {"C", 12}, {"4", 4}, {"5", 5}, {"6", 6}, {"D", 13}, - {"7", 7}, {"8", 8}, {"9", 9}, {"D", 14}, - {"A", 10}, {"0", 0}, {"B", 11}, {"F", 15} + {"7", 7}, {"8", 8}, {"9", 9}, {"E", 14}, + {"A", 10}, {"0", 0}, {"B", 11}, {"F", 15}, } - btn_width := f32(rect.width / 4) - btn_height := f32(rect.height / 4) + btn_width := content.width / 4 + btn_height := content.height / 4 for val, idx in keys { str := strings.clone_to_cstring(val.label) - ri := int(idx / 4) - ci := idx % 4 + defer delete(str) - irect := rl.Rectangle{ - x = btn_width * f32(ci), - y = (btn_height * f32(ri)) + rect.y, - width = btn_width, + ri := idx / 4 + ci := idx % 4 + irect := rl.Rectangle { + x = content.x + btn_width * f32(ci), + y = content.y + btn_height * f32(ri), + width = btn_width, height = btn_height, } - if(display[val.index]) { rl.DrawRectangleRec(irect, rl.DARKGRAY) } - rl.DrawRectangleLinesEx(irect, 1, rl.GRAY) - rl.DrawTextEx(font, str, rl.Vector2{irect.x + btn_width / 2, irect.y + btn_height / 2}, 18, 1, rl.WHITE) + if display[val.index] { rl.DrawRectangleRec(irect, rl.BLACK) } - // Free the allocations! - delete(str) + rl.DrawRectangleLinesEx(irect, 1, rl.GRAY) + rl.DrawTextEx( font, str, + rl.Vector2{irect.x + btn_width / 2, irect.y + btn_height / 2}, + KEYPAD_FONT_SIZE, + 1, + rl.WHITE, + ) } }