Cleaning up ui components making uniform.

This commit is contained in:
2026-06-13 09:31:32 +02:00
parent d28aa8a401
commit 2c664b24a9
4 changed files with 138 additions and 93 deletions
+8 -12
View File
@@ -7,27 +7,23 @@ PADDING :: 10
gui_control_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) { gui_control_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY)
// Small text area
// Control bar buttons // Cursor moves for every btn call places them left to right with padding
btn_w : f32 = 80 cursor : f32 = rect.x + PANEL_PADDING
btn_h : f32 = rect.height - (PADDING * 2)
gap : f32 = 6
cursor : f32 = rect.x + PADDING
if btn(&cursor, rect, btn_h, btn_w, gap, "RUN") { if btn(&cursor, rect, BUTTON_HEIGHT, BUTTON_WIDTH, PANEL_PADDING, "RUN") {
log.info("RUN clicked") if sim.rom_loaded {
sim.paused = false sim.paused = false
sim.running = true sim.running = true
} else {
log.info("no rom selected, can't run")
}
} }
if btn(&cursor, rect, btn_h, btn_w, gap, "PAUSE") { if btn(&cursor, rect, BUTTON_HEIGHT, BUTTON_WIDTH, PANEL_PADDING, "PAUSE") {
log.info("PAUSE clicked")
sim.paused = true sim.paused = true
sim.running = false sim.running = false
} }
if btn(&cursor, rect, btn_h, btn_w, gap, "STEP") { log.info("STEP clicked") }
} }
btn :: proc(cursor: ^f32, rect: rl.Rectangle, h, w, gap: f32, label: cstring) -> bool { btn :: proc(cursor: ^f32, rect: rl.Rectangle, h, w, gap: f32, label: cstring) -> bool {
+52 -33
View File
@@ -8,24 +8,23 @@ WINDOW_WIDTH :: 1920
WINDOW_HEIGHT :: 1080 WINDOW_HEIGHT :: 1080
// @TODO: If this grows lets move it into its own file // @TODO: If this grows lets move it into its own file
// ─── Layout constants ───────────────────────────────────────────────────
SIDEBAR_PERCENT :: 0.20 SIDEBAR_PERCENT :: 0.20
DISPLAY_PERCENT :: 0.30 DISPLAY_PERCENT :: 0.30
CONTROL_BAR_H :: f32(50) CONTROL_BAR_H :: f32(50)
STATUS_BAR_H :: f32(30) STATUS_BAR_H :: f32(30)
// ─── Layout constants ───────────────────────────────────────────────────
PANEL_PADDING :: 10 PANEL_PADDING :: 10
PANEL_HEADER :: 24 PANEL_HEADER :: 24
BUTTON_HEIGHT :: 30 BUTTON_HEIGHT :: 30
BUTTON_WIDTH :: 120 BUTTON_WIDTH :: 120
DROP_FONT_SIZE :: 20 BIG_FONT_SIZE :: 20
KEYPAD_FONT_SIZE :: 18 KEYPAD_FONT_SIZE :: 18
Layout :: struct { Layout :: struct {
control_bar : rl.Rectangle, control_bar : rl.Rectangle,
left_panel : rl.Rectangle, left_panel : rl.Rectangle,
display : rl.Rectangle, display : rl.Rectangle,
bottom_panel : rl.Rectangle,
right_panel : rl.Rectangle, right_panel : rl.Rectangle,
status_bar : rl.Rectangle, status_bar : rl.Rectangle,
} }
@@ -63,8 +62,8 @@ run_gui :: proc(sim: ^Simulator) {
rl.BeginDrawing() rl.BeginDrawing()
rl.ClearBackground(rl.BLACK) rl.ClearBackground(rl.BLACK)
// Cycle the machine to update memory etc
if (!sim.paused) { if (!sim.paused) {
// Cycle the machine to update memory etc
emu.run_machine(sim.machine, 12) emu.run_machine(sim.machine, 12)
// Handle delay timer // Handle delay timer
@@ -78,16 +77,11 @@ run_gui :: proc(sim: ^Simulator) {
} else { } else {
rl.StopSound(beep) rl.StopSound(beep)
} }
} }
gui_control_bar(layout.control_bar, sim) gui_control_bar(layout.control_bar, sim)
gui_left_panel(layout.left_panel, sim) gui_left_panel(layout.left_panel, sim)
// gui_right_panel(layout.right_panel, s.machine) gui_screen(layout.display, sim)
// Screen is just drawing the display buffer just needs that as arg
// Not the whole sim struct
gui_screen(layout.display, sim.machine)
gui_status_bar(layout.status_bar, sim) gui_status_bar(layout.status_bar, sim)
rl.EndDrawing() rl.EndDrawing()
@@ -101,39 +95,64 @@ run_gui :: proc(sim: ^Simulator) {
// @TODO: If this grows lets move it into its own file // @TODO: If this grows lets move it into its own file
calc_layout :: proc(screen_width: f32, screen_height: f32) -> Layout { calc_layout :: proc(screen_width: f32, screen_height: f32) -> Layout {
sidebar_width := screen_width * SIDEBAR_PERCENT top_h := CONTROL_BAR_H
content_height := screen_height - CONTROL_BAR_H - STATUS_BAR_H bottom_h := STATUS_BAR_H
display_height := screen_height * DISPLAY_PERCENT - CONTROL_BAR_H - STATUS_BAR_H content_h := screen_height - top_h - bottom_h
content_y := top_h
sidebar_w := screen_width * SIDEBAR_PERCENT
screen_h_ratio := 0.40
bottom_panel_h := content_h * f32(1.0 - screen_h_ratio)
screen_h := content_h * f32(screen_h_ratio)
memory_h := content_h - screen_h
center_x := sidebar_w
center_w := screen_width - sidebar_w * 2
return Layout { return Layout {
control_bar = rl.Rectangle { control_bar = rl.Rectangle{
x = 0, x = 0,
y = 0, y = 0,
width = screen_width, width = screen_width,
height = CONTROL_BAR_H, height = top_h,
}, },
left_panel = rl.Rectangle {
left_panel = rl.Rectangle{
x = 0, x = 0,
y = CONTROL_BAR_H, y = top_h,
width = sidebar_width, width = sidebar_w,
height = content_height, height = content_h,
}, },
display = rl.Rectangle {
x = sidebar_width, // CHIP-8 screen (top center)
y = CONTROL_BAR_H, display = rl.Rectangle{
width = screen_width - (sidebar_width * 2), x = center_x,
height = display_height, y = top_h,
width = center_w,
height = screen_h,
}, },
right_panel = rl.Rectangle {
x = screen_width - sidebar_width, // MEMORY / DEBUG panel (bottom center)
y = CONTROL_BAR_H, bottom_panel = rl.Rectangle{
width = sidebar_width, x = center_x,
height = content_height, y = top_h + screen_h,
width = center_w,
height = memory_h,
}, },
status_bar = rl.Rectangle {
right_panel = rl.Rectangle{
x = screen_width - sidebar_w,
y = top_h,
width = sidebar_w,
height = content_h,
},
status_bar = rl.Rectangle{
x = 0, x = 0,
y = screen_height - STATUS_BAR_H, y = screen_height - bottom_h,
width = screen_width, height = STATUS_BAR_H, width = screen_width,
height = bottom_h,
}, },
} }
} }
+36 -22
View File
@@ -1,38 +1,52 @@
package simulator package simulator
import m "../machine"
import rl "vendor:raylib" import rl "vendor:raylib"
gui_screen :: proc(rect: rl.Rectangle, s: ^m.System) { gui_screen :: proc(rect: rl.Rectangle, sim: ^Simulator) {
// Make sure screen is staying in its aspect ratio s := sim.machine
chip8_aspect := f32(64.0 / 32.0)
available_aspect := rect.width / rect.height
screen_rect := rect
if available_aspect > chip8_aspect { // 2 : 1
// Area is too wide // 2 so, for every 1 unit of height I have 2 units of width
screen_rect.width = rect.height * chip8_aspect // twice as wide as it is tall, or half as tall as it is wide
screen_rect.x = rect.x + (rect.width - screen_rect.width) / 2 aspect_ratio : f32 = 64.0 / 32.0
// create viewport for the ratio
view := rect
avail_space := rect.width / rect.height
if avail_space > aspect_ratio {
view.width = rect.height * aspect_ratio
view.x = rect.x + (rect.width - view.width) * 0.5
} else { } else {
// Area is too tall view.height = rect.width / aspect_ratio
screen_rect.height = rect.width / chip8_aspect view.y = rect.y + (rect.height - view.height) * 0.5
screen_rect.y = rect.y + (rect.height - screen_rect.height) / 2
} }
pixel_size := min(int(screen_rect.width / 64), int(screen_rect.height / 32)) // get scale
pixel_size = max(pixel_size, 1) pixel := min(int(view.width / 64), int(view.height / 32))
pixel = max(pixel, 1)
actual_width := pixel_size * 64 draw_w := pixel * 64
actual_height := pixel_size * 32 draw_h := pixel * 32
display_x := i32(screen_rect.x) + i32(int(screen_rect.width) - actual_width) / 2 // center frame
display_y := i32(screen_rect.y) + i32(int(screen_rect.height) - actual_height) / 2 x := i32(view.x + (view.width - f32(draw_w)) * 0.5)
y := i32(view.y + (view.height - f32(draw_h)) * 0.5)
// Debug borders
rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY)
rl.DrawRectangleLinesEx(screen_rect, 2, rl.WHITE) rl.DrawRectangleLinesEx(view, 2, rl.WHITE)
render_display(&s.display, display_x, display_y, i32(pixel_size)) if !sim.rom_loaded {
// centered drop-zone text
text: cstring = "PLEASE SELECT AND LOAD A CHIP 8 ROM"
text_width := rl.MeasureText(text, BIG_FONT_SIZE)
text_x := view.x + (view.width - f32(text_width)) * 0.6
text_y := view.y + (view.height - f32(BIG_FONT_SIZE)) * 0.5
rl.DrawTextEx(sim.font, text, {text_x,text_y}, BIG_FONT_SIZE, 1, rl.WHITE)
} else {
render_display(&s.display, x, y, i32(pixel))
}
} }
@(private = "file") @(private = "file")
+17 -1
View File
@@ -3,7 +3,9 @@ package simulator
import "core:fmt" import "core:fmt"
import rl "vendor:raylib" import rl "vendor:raylib"
// @TODO: render status bar text
gui_status_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) { gui_status_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
// Left to right text draws
rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY)
cursor: f32 = rect.x + PADDING cursor: f32 = rect.x + PADDING
@@ -16,7 +18,21 @@ gui_status_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
} }
status_divider(&cursor, cy) status_divider(&cursor, cy)
status_text(&cursor, cy, fmt.ctprintf("FPS: %d", rl.GetFPS()), sim.font) status_text(&cursor, cy, fmt.ctprintf("Rom Loaded: %v", sim.rom_loaded), sim.font)
// FPS set far right
fps_text := fmt.ctprintf("FPS: %d", rl.GetFPS())
fps_width := rl.MeasureTextEx(sim.font, fps_text, f32(sim.font.baseSize), 1).x
fps_x := rect.x + rect.width - PADDING - fps_width
rl.DrawTextEx(
sim.font,
fps_text,
{fps_x, cy - f32(sim.font.baseSize) * 0.5},
f32(sim.font.baseSize),
1,
rl.RAYWHITE,
)
} }
StatusIconShape :: enum { CIRCLE, SQUARE } StatusIconShape :: enum { CIRCLE, SQUARE }