From e6feabe2f1b7972f0af10091704394ba0d2fafed Mon Sep 17 00:00:00 2001 From: Jason Hilder Date: Wed, 3 Jun 2026 07:04:04 +0200 Subject: [PATCH] Gui code neatened up for easy components. Updated the gui init etc to use a layout struct to quickly setup new rectangles for the gui. Each component can use its rect as its bounding box for ui elements, each can set its own padding etc per panel --- src/gui/control_bar.odin | 8 +++++ src/gui/gui.odin | 64 ++++++++++++++++++++++++++++++++------ src/gui/left_panel.odin | 8 +++++ src/gui/right_panel.odin | 8 +++++ src/gui/screen.odin | 66 ++++++++++++---------------------------- 5 files changed, 97 insertions(+), 57 deletions(-) create mode 100644 src/gui/control_bar.odin create mode 100644 src/gui/left_panel.odin create mode 100644 src/gui/right_panel.odin diff --git a/src/gui/control_bar.odin b/src/gui/control_bar.odin new file mode 100644 index 0000000..c446d48 --- /dev/null +++ b/src/gui/control_bar.odin @@ -0,0 +1,8 @@ +package gui + +import m "../machine" +import rl "vendor:raylib" + +gui_control_bar :: proc(rect: rl.Rectangle, s: ^m.System) { + rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) +} diff --git a/src/gui/gui.odin b/src/gui/gui.odin index efb95c4..d218641 100644 --- a/src/gui/gui.odin +++ b/src/gui/gui.odin @@ -7,6 +7,18 @@ import rl "vendor:raylib" WINDOW_WIDTH :: 1920 WINDOW_HEIGHT :: 1080 +// TODO: If this grows lets move it into its own file +SIDEBAR_PERCENT :: 0.20 +DISPLAY_PERCENT :: 0.30 +CONTROLBAR_PERCENT :: 0.05 + +Layout :: struct { + left_panel : rl.Rectangle, + right_panel : rl.Rectangle, + display : rl.Rectangle, + control_bar : rl.Rectangle, +} + // Initialize main the gui 'window' init_gui :: proc(s: ^m.System) { rl.SetConfigFlags({.WINDOW_RESIZABLE}) @@ -20,15 +32,9 @@ init_gui :: proc(s: ^m.System) { // Pass these down to gui functions so they can setup their sizes? screen_width := f32(rl.GetScreenWidth()) screen_height := f32(rl.GetScreenHeight()) - sidebar_width := screen_width * 0.20 - display_rect := rl.Rectangle{ - x = sidebar_width, - y = 0, - width = screen_width - (sidebar_width * 2), - height = screen_height * 0.30, - } + layout := calc_layout(screen_width, screen_height) rl.BeginDrawing() rl.ClearBackground(rl.BLACK) @@ -42,12 +48,50 @@ init_gui :: proc(s: ^m.System) { } // -------------------------------------- - // run each gui "component" - gui_screen(display_rect, s) + gui_left_panel(layout.left_panel, s) + gui_right_panel(layout.right_panel, s) + gui_screen(layout.display, s) + gui_control_bar(layout.control_bar, s) rl.EndDrawing() } rl.CloseAudioDevice() rl.CloseWindow() -} \ No newline at end of file +} + +// TODO: If this grows lets move it into its own file +calc_layout :: proc(screen_width: f32, screen_height: f32) -> Layout { + sidebar_width := screen_width * SIDEBAR_PERCENT + display_height := screen_height * DISPLAY_PERCENT + + return Layout { + left_panel = rl.Rectangle { + x = 0, + y = 0, + width = sidebar_width, + height = screen_height + }, + + right_panel = rl.Rectangle { + x = screen_width - sidebar_width, + y = 0, + width = sidebar_width, + height = screen_height + }, + + display = rl.Rectangle { + x = sidebar_width, + y = 0, + width = screen_width - (sidebar_width * 2), + height = display_height + }, + + control_bar = rl.Rectangle { + x = sidebar_width, + y = 0, + width = screen_width - (sidebar_width * 2), + height = (screen_height * 0.05) + display_height + } + } +} diff --git a/src/gui/left_panel.odin b/src/gui/left_panel.odin new file mode 100644 index 0000000..446a31e --- /dev/null +++ b/src/gui/left_panel.odin @@ -0,0 +1,8 @@ +package gui + +import m "../machine" +import rl "vendor:raylib" + +gui_left_panel :: proc(rect: rl.Rectangle, s: ^m.System) { + rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) +} diff --git a/src/gui/right_panel.odin b/src/gui/right_panel.odin new file mode 100644 index 0000000..9e06099 --- /dev/null +++ b/src/gui/right_panel.odin @@ -0,0 +1,8 @@ +package gui + +import m "../machine" +import rl "vendor:raylib" + +gui_right_panel :: proc(rect: rl.Rectangle, s: ^m.System) { + rl.DrawRectangleLinesEx(rect, 1, rl.GREEN) +} diff --git a/src/gui/screen.odin b/src/gui/screen.odin index adc815c..3376dd1 100644 --- a/src/gui/screen.odin +++ b/src/gui/screen.odin @@ -3,56 +3,33 @@ package gui import m "../machine" import rl "vendor:raylib" -control_bar_height :: f32(20.0) +gui_screen :: proc(rect: rl.Rectangle, s: ^m.System) { + // Make sure screen is staying in its aspect ratio + chip8_aspect := f32(64.0 / 32.0) + available_aspect := rect.width / rect.height + screen_rect := rect -gui_screen :: proc(window_rect: rl.Rectangle, s: ^m.System) { - control_bar_rect := rl.Rectangle{ - x = window_rect.x, - y = window_rect.y, - width = window_rect.width, - height = control_bar_height + if available_aspect > chip8_aspect { + // Area is too wide + screen_rect.width = rect.height * chip8_aspect + screen_rect.x = rect.x + (rect.width - screen_rect.width) / 2 + } else { + // Area is too tall + screen_rect.height = rect.width / chip8_aspect + screen_rect.y = rect.y + (rect.height - screen_rect.height) / 2 } - content_rect := rl.Rectangle{ - x = window_rect.x, - y = window_rect.y + control_bar_height, - width = window_rect.width, - height = window_rect.height - control_bar_height - } - - chip8_aspect := f32(64.0 / 32.0) - available_aspect := content_rect.width / content_rect.height - - screen_rect := content_rect - - if available_aspect > chip8_aspect { - // Content area is too wide - screen_rect.height = content_rect.height - screen_rect.width = content_rect.height * chip8_aspect - - screen_rect.x = content_rect.x + (content_rect.width - screen_rect.width) / 2 - screen_rect.y = content_rect.y - } else { - // Content area is too tall - screen_rect.width = content_rect.width - screen_rect.height = content_rect.width / chip8_aspect - - screen_rect.x = content_rect.x - screen_rect.y = content_rect.y + (content_rect.height - screen_rect.height) / 2 - } - - pixel_size := min(int(screen_rect.width / 64), int(screen_rect.height / 32)) + pixel_size := min(int(screen_rect.width / 64), int(screen_rect.height / 32)) pixel_size = max(pixel_size, 1) actual_width := pixel_size * 64 actual_height := pixel_size * 32 - display_x := i32(int(screen_rect.x) + (int(screen_rect.width) - actual_width) / 2) - display_y := i32(int(screen_rect.y) + (int(screen_rect.height) - actual_height) / 2) + display_x := i32(screen_rect.x) + i32(int(screen_rect.width) - actual_width) / 2 + display_y := i32(screen_rect.y) + i32(int(screen_rect.height) - actual_height) / 2 // Debug borders - rl.DrawRectangleLinesEx(window_rect, 1, rl.DARKGRAY) - rl.DrawRectangleLinesEx(control_bar_rect, 1, rl.GREEN) + rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) rl.DrawRectangleLinesEx(screen_rect, 2, rl.WHITE) render_display(&s.display, display_x, display_y, i32(pixel_size)) @@ -60,17 +37,12 @@ gui_screen :: proc(window_rect: rl.Rectangle, s: ^m.System) { @(private = "file") render_display :: proc(display_buffer: ^[32][64]u8, offset_x, offset_y, scale: i32) { - // Fill display area with black background rl.DrawRectangle(offset_x, offset_y, 64 * scale, 32 * scale, rl.BLACK) + for y in 0..