Created
June 22, 2025 09:27
-
-
Save naranyala/09b8c02be1c8f196f972a3e644e546e1 to your computer and use it in GitHub Desktop.
dashboard layout build with odin+raylib
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "core:slice" | |
import "core:strings" | |
import rl "vendor:raylib" | |
main :: proc() { | |
// Initialize window | |
rl.InitWindow(1000, 600, "Dropdown List With Shape Names") | |
defer rl.CloseWindow() | |
rl.SetTargetFPS(60) | |
// UI constants | |
WINDOW_WIDTH :: 1000 | |
WINDOW_HEIGHT :: 600 | |
SIDEBAR_WIDTH :: 300 | |
DROPDOWN_X :: 20 | |
DROPDOWN_Y :: 20 | |
DROPDOWN_WIDTH :: 260 | |
DROPDOWN_HEIGHT :: 30 | |
TEXT_SIZE :: 20 | |
LIST_X :: 20 | |
LIST_Y :: 120 // Moved down to avoid overlap | |
LIST_LINE_HEIGHT :: 25 | |
CLICK_COOLDOWN :: 0.1 // Debounce time in seconds | |
DISPLAY_X :: SIDEBAR_WIDTH + 20 | |
DISPLAY_Y :: WINDOW_HEIGHT / 2 | |
DISPLAY_TEXT_SIZE :: 40 | |
// UI states | |
show_dropdown := false | |
dropdown_pos := rl.Vector2{f32(DROPDOWN_X), f32(DROPDOWN_Y)} | |
dropdown_width: f32 = DROPDOWN_WIDTH | |
dropdown_height: f32 = DROPDOWN_HEIGHT | |
selected_dropdown := -1 | |
last_mouse_press_time: f64 = -1 // For debouncing | |
selected_shape: string // Selected shape name | |
// Dropdown items and precomputed C strings | |
dropdown_items := []string{"2D Shapes", "3D Shapes"} | |
dropdown_cstrings: [dynamic]cstring | |
defer delete(dropdown_cstrings) | |
for item in dropdown_items { | |
append(&dropdown_cstrings, strings.clone_to_cstring(item)) | |
} | |
// Shape lists and precomputed C strings | |
shape_2d := []string{"Circle", "Rectangle", "Triangle", "Line", "Ellipse", "Polygon"} | |
shape_3d := []string{"Cube", "Sphere", "Cylinder", "Torus", "Cone", "Plane"} | |
shape_2d_cstrings, shape_3d_cstrings: [dynamic]cstring | |
defer delete(shape_2d_cstrings) | |
defer delete(shape_3d_cstrings) | |
for item in shape_2d { | |
append(&shape_2d_cstrings, strings.clone_to_cstring(item)) | |
} | |
for item in shape_3d { | |
append(&shape_3d_cstrings, strings.clone_to_cstring(item)) | |
} | |
for !rl.WindowShouldClose() { | |
current_time := rl.GetTime() | |
rl.BeginDrawing() | |
defer rl.EndDrawing() | |
rl.ClearBackground(rl.RAYWHITE) | |
// --- Sidebar --- | |
rl.DrawRectangle(0, 0, SIDEBAR_WIDTH, WINDOW_HEIGHT, rl.LIGHTGRAY) | |
// --- Dropdown Toggle Button --- | |
toggle_rect := rl.Rectangle { | |
dropdown_pos.x, | |
dropdown_pos.y, | |
dropdown_width, | |
dropdown_height, | |
} | |
rl.DrawRectangleRec(toggle_rect, rl.WHITE) | |
toggle_text := | |
selected_dropdown >= 0 ? dropdown_cstrings[selected_dropdown] : "Select Category" | |
rl.DrawText( | |
toggle_text, | |
cast(i32)(dropdown_pos.x + 10), | |
cast(i32)(dropdown_pos.y + 8), | |
TEXT_SIZE, | |
rl.DARKGRAY, | |
) | |
// --- Dropdown Items --- | |
dropdown_bounds := toggle_rect | |
dropdown_items_rects: [dynamic]rl.Rectangle | |
defer delete(dropdown_items_rects) | |
if show_dropdown { | |
for i in 0 ..< len(dropdown_items) { | |
item_y := dropdown_pos.y + f32(i + 1) * dropdown_height | |
item_rect := rl.Rectangle{dropdown_pos.x, item_y, dropdown_width, dropdown_height} | |
append(&dropdown_items_rects, item_rect) | |
dropdown_bounds.height += dropdown_height // Expand bounds to include items | |
// Highlight on hover | |
is_hovered := rl.CheckCollisionPointRec(rl.GetMousePosition(), item_rect) | |
color := is_hovered ? rl.GRAY : rl.WHITE | |
rl.DrawRectangleRec(item_rect, color) | |
rl.DrawRectangleLines( | |
cast(i32)item_rect.x, | |
cast(i32)item_rect.y, | |
cast(i32)item_rect.width, | |
cast(i32)item_rect.height, | |
rl.DARKGRAY, | |
) | |
rl.DrawText( | |
dropdown_cstrings[i], | |
cast(i32)(item_rect.x + 10), | |
cast(i32)(item_rect.y + 8), | |
TEXT_SIZE, | |
rl.DARKGRAY, | |
) | |
} | |
} | |
// --- Shape List --- | |
shape_list_rects: [dynamic]rl.Rectangle | |
defer delete(shape_list_rects) | |
if selected_dropdown >= 0 && selected_dropdown < len(dropdown_items) { | |
// Calculate dynamic list position to avoid overlap | |
list_start_y: i32 = LIST_Y | |
if show_dropdown { | |
// If dropdown is open, start list below the dropdown items | |
dropdown_bottom := dropdown_pos.y + f32(len(dropdown_items) + 1) * dropdown_height | |
list_start_y = cast(i32)(dropdown_bottom + 20) // Add some padding | |
} | |
selected_list: []cstring | |
selected_list_strings: []string | |
switch selected_dropdown { | |
case 0: | |
selected_list = shape_2d_cstrings[:] | |
selected_list_strings = shape_2d | |
case 1: | |
selected_list = shape_3d_cstrings[:] | |
selected_list_strings = shape_3d | |
case: | |
selected_list = {} | |
selected_list_strings = {} | |
} | |
for i in 0 ..< len(selected_list) { | |
item_rect := rl.Rectangle { | |
f32(LIST_X), | |
f32(list_start_y + cast(i32)(i * LIST_LINE_HEIGHT)), | |
DROPDOWN_WIDTH, | |
f32(LIST_LINE_HEIGHT), | |
} | |
append(&shape_list_rects, item_rect) | |
is_hovered := rl.CheckCollisionPointRec(rl.GetMousePosition(), item_rect) | |
color := is_hovered ? rl.GRAY : rl.WHITE | |
rl.DrawRectangleRec(item_rect, color) | |
rl.DrawRectangleLines( | |
cast(i32)item_rect.x, | |
cast(i32)item_rect.y, | |
cast(i32)item_rect.width, | |
cast(i32)item_rect.height, | |
rl.LIGHTGRAY, | |
) | |
rl.DrawText( | |
selected_list[i], | |
cast(i32)LIST_X + 10, | |
cast(i32)(list_start_y + cast(i32)(i * LIST_LINE_HEIGHT) + 2), | |
TEXT_SIZE, | |
rl.MAROON, | |
) | |
} | |
} | |
// --- Right Section: Display Selected Shape --- | |
if selected_shape != "" { | |
shape_cstring := strings.clone_to_cstring(selected_shape) | |
defer delete(shape_cstring) | |
rl.DrawText(shape_cstring, DISPLAY_X, DISPLAY_Y, DISPLAY_TEXT_SIZE, rl.BLACK) | |
} else { | |
rl.DrawText("Select a shape", DISPLAY_X, DISPLAY_Y, DISPLAY_TEXT_SIZE, rl.GRAY) | |
} | |
// --- Handle Input --- | |
if rl.IsMouseButtonPressed(rl.MouseButton.LEFT) && | |
current_time >= last_mouse_press_time + CLICK_COOLDOWN { | |
mouse := rl.GetMousePosition() | |
last_mouse_press_time = current_time | |
// Dropdown toggle | |
if rl.CheckCollisionPointRec(mouse, toggle_rect) { | |
show_dropdown = !show_dropdown | |
} else if show_dropdown { | |
// Check dropdown item selection | |
dropdown_item_clicked := false | |
for i in 0 ..< len(dropdown_items_rects) { | |
if rl.CheckCollisionPointRec(mouse, dropdown_items_rects[i]) { | |
selected_dropdown = i | |
show_dropdown = false | |
selected_shape = "" // Reset shape selection | |
dropdown_item_clicked = true | |
break | |
} | |
} | |
// Close dropdown if clicked outside | |
if !dropdown_item_clicked { | |
show_dropdown = false | |
} | |
} | |
// Shape list selection (only if dropdown is not open) | |
if !show_dropdown && selected_dropdown >= 0 { | |
selected_list_strings: []string | |
switch selected_dropdown { | |
case 0: | |
selected_list_strings = shape_2d | |
case 1: | |
selected_list_strings = shape_3d | |
case: | |
selected_list_strings = {} | |
} | |
for i in 0 ..< len(shape_list_rects) { | |
if rl.CheckCollisionPointRec(mouse, shape_list_rects[i]) { | |
selected_shape = selected_list_strings[i] | |
break | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment