mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-25 14:15:02 +00:00
240 lines
7.5 KiB
Lua
240 lines
7.5 KiB
Lua
local Gui = require('gui')
|
|
local math3d = require('math3d')
|
|
|
|
local ctx = Gui.newContext()
|
|
local input = Gui.newInputState()
|
|
|
|
local function log_trace(fmt, ...)
|
|
if not lua_debug or not fmt then
|
|
return
|
|
end
|
|
print(string.format(fmt, ...))
|
|
end
|
|
|
|
local buttonStates = {
|
|
button1 = false,
|
|
button2 = false,
|
|
button3 = false,
|
|
button4 = false
|
|
}
|
|
|
|
local statusMessage = 'Ready'
|
|
local viewProjectionLogged = false
|
|
local fpsMode = false
|
|
local fpsToggleWasDown = false
|
|
local fpsToggleKey = "F1"
|
|
if type(config) == "table" then
|
|
local bindings = config.input_bindings
|
|
if type(bindings) == "table" then
|
|
local key = bindings.fps_toggle or bindings.fps_toggle_key
|
|
if type(key) == "string" or type(key) == "number" then
|
|
fpsToggleKey = key
|
|
end
|
|
end
|
|
end
|
|
|
|
local function setFpsMode(enabled)
|
|
fpsMode = enabled
|
|
if window_set_relative_mouse_mode then
|
|
window_set_relative_mouse_mode(enabled)
|
|
end
|
|
if window_set_mouse_grabbed then
|
|
window_set_mouse_grabbed(enabled)
|
|
end
|
|
if window_set_cursor_visible then
|
|
window_set_cursor_visible(not enabled)
|
|
end
|
|
statusMessage = enabled and "FPS mode enabled" or "FPS mode disabled"
|
|
log_trace("FPS mode toggled: %s", enabled and "on" or "off")
|
|
end
|
|
|
|
local function updateFpsModeToggle()
|
|
if not input_is_key_down then
|
|
return
|
|
end
|
|
if fpsToggleKey == nil or fpsToggleKey == "" then
|
|
return
|
|
end
|
|
local down = input_is_key_down(fpsToggleKey)
|
|
if down and not fpsToggleWasDown then
|
|
setFpsMode(not fpsMode)
|
|
end
|
|
fpsToggleWasDown = down
|
|
if fpsMode and window_get_mouse_grabbed and not window_get_mouse_grabbed() then
|
|
fpsMode = false
|
|
statusMessage = "FPS mode disabled"
|
|
end
|
|
end
|
|
|
|
local function build_shader_variants()
|
|
local ok, toolkit = pcall(require, "shader_toolkit")
|
|
if not ok then
|
|
error("Shader toolkit unavailable: " .. tostring(toolkit))
|
|
end
|
|
|
|
local ok_generate, variant = pcall(toolkit.generate_variant, {
|
|
key = "default",
|
|
template = "gui_2d",
|
|
output_mode = "source",
|
|
compile = false,
|
|
})
|
|
if not ok_generate then
|
|
error("Shader generation failed: " .. tostring(variant))
|
|
end
|
|
|
|
return {default = variant}
|
|
end
|
|
|
|
local shader_variants = build_shader_variants()
|
|
|
|
local function drawTestButtons()
|
|
-- Background panel
|
|
ctx:pushRect({x = 50, y = 50, width = 400, height = 400}, {
|
|
color = {0.1, 0.1, 0.1, 0.9},
|
|
borderColor = {0.5, 0.5, 0.5, 1.0},
|
|
})
|
|
|
|
-- Title
|
|
Gui.text(ctx, {x = 70, y = 70, width = 360, height = 40}, "2D Test Buttons", {
|
|
fontSize = 28,
|
|
alignX = "center",
|
|
color = {1.0, 1.0, 1.0, 1.0},
|
|
})
|
|
|
|
-- Button 1
|
|
if Gui.button(ctx, "btn1", {x = 100, y = 130, width = 150, height = 50}, "Button 1") then
|
|
buttonStates.button1 = not buttonStates.button1
|
|
statusMessage = "Button 1 " .. (buttonStates.button1 and "pressed" or "released")
|
|
log_trace("Button 1 clicked: %s", statusMessage)
|
|
end
|
|
|
|
-- Button 2
|
|
if Gui.button(ctx, "btn2", {x = 270, y = 130, width = 150, height = 50}, "Button 2") then
|
|
buttonStates.button2 = not buttonStates.button2
|
|
statusMessage = "Button 2 " .. (buttonStates.button2 and "pressed" or "released")
|
|
log_trace("Button 2 clicked: %s", statusMessage)
|
|
end
|
|
|
|
-- Button 3
|
|
if Gui.button(ctx, "btn3", {x = 100, y = 200, width = 150, height = 50}, "Button 3") then
|
|
buttonStates.button3 = not buttonStates.button3
|
|
statusMessage = "Button 3 " .. (buttonStates.button3 and "pressed" or "released")
|
|
log_trace("Button 3 clicked: %s", statusMessage)
|
|
end
|
|
|
|
-- Button 4
|
|
if Gui.button(ctx, "btn4", {x = 270, y = 200, width = 150, height = 50}, "Button 4") then
|
|
buttonStates.button4 = not buttonStates.button4
|
|
statusMessage = "Button 4 " .. (buttonStates.button4 and "pressed" or "released")
|
|
log_trace("Button 4 clicked: %s", statusMessage)
|
|
end
|
|
|
|
-- Status display
|
|
Gui.text(ctx, {x = 70, y = 280, width = 360, height = 30}, "Status: " .. statusMessage, {
|
|
fontSize = 18,
|
|
alignX = "center",
|
|
color = {0.8, 0.8, 1.0, 1.0},
|
|
})
|
|
|
|
-- Button states display
|
|
local statesText = string.format("States: 1:%s 2:%s 3:%s 4:%s",
|
|
buttonStates.button1 and "ON" or "OFF",
|
|
buttonStates.button2 and "ON" or "OFF",
|
|
buttonStates.button3 and "ON" or "OFF",
|
|
buttonStates.button4 and "ON" or "OFF")
|
|
Gui.text(ctx, {x = 70, y = 315, width = 360, height = 22}, statesText, {
|
|
fontSize = 16,
|
|
alignX = "center",
|
|
color = {1.0, 0.8, 0.8, 1.0},
|
|
})
|
|
|
|
local deltaX = input.mouseDeltaX or 0
|
|
local deltaY = input.mouseDeltaY or 0
|
|
Gui.text(ctx, {x = 70, y = 340, width = 360, height = 20},
|
|
string.format("Mouse d: %.1f, %.1f", deltaX, deltaY), {
|
|
fontSize = 14,
|
|
alignX = "center",
|
|
color = {0.85, 0.9, 0.85, 1.0},
|
|
})
|
|
|
|
local grabState = window_get_mouse_grabbed and window_get_mouse_grabbed() or false
|
|
local fpsLabel = fpsMode and "ON" or "OFF"
|
|
local fpsToggleLabel = tostring(fpsToggleKey or "F1")
|
|
Gui.text(ctx, {x = 70, y = 362, width = 360, height = 20},
|
|
string.format("FPS Mode: %s (grab=%s, %s toggle)", fpsLabel, grabState and "on" or "off", fpsToggleLabel), {
|
|
fontSize = 14,
|
|
alignX = "center",
|
|
color = {0.85, 0.85, 0.95, 1.0},
|
|
})
|
|
|
|
if Gui.button(ctx, "fps_toggle", {x = 155, y = 385, width = 140, height = 28},
|
|
fpsMode and "FPS: ON" or "FPS: OFF") then
|
|
setFpsMode(not fpsMode)
|
|
end
|
|
|
|
-- Reset button
|
|
if Gui.button(ctx, "reset", {x = 175, y = 418, width = 100, height = 28}, "Reset") then
|
|
buttonStates.button1 = false
|
|
buttonStates.button2 = false
|
|
buttonStates.button3 = false
|
|
buttonStates.button4 = false
|
|
statusMessage = "All buttons reset"
|
|
log_trace("Reset button clicked")
|
|
end
|
|
end
|
|
|
|
gui_context = ctx
|
|
gui_input = input
|
|
|
|
function get_scene_objects()
|
|
return {} -- No 3D objects
|
|
end
|
|
|
|
function get_shader_paths()
|
|
local default_variant = shader_variants.default or {}
|
|
local vertex_label = default_variant.vertex or "inline"
|
|
local fragment_label = default_variant.fragment or "inline"
|
|
log_trace("GUI demo shader variants: default vertex=%s fragment=%s",
|
|
vertex_label,
|
|
fragment_label)
|
|
return shader_variants
|
|
end
|
|
|
|
function get_view_projection(aspect)
|
|
if not viewProjectionLogged then
|
|
log_trace("GUI demo view projection: identity (aspect=%.2f)", aspect)
|
|
viewProjectionLogged = true
|
|
end
|
|
return math3d.identity()
|
|
end
|
|
|
|
function get_gui_commands()
|
|
updateFpsModeToggle()
|
|
ctx:beginFrame(input)
|
|
drawTestButtons()
|
|
if fpsMode then
|
|
local width, height = 1024, 768
|
|
if window_get_size then
|
|
local w, h = window_get_size()
|
|
if type(w) == "number" and type(h) == "number" then
|
|
width, height = w, h
|
|
end
|
|
end
|
|
Gui.cursor(ctx, {mouseX = width * 0.5, mouseY = height * 0.5, mouseDown = input.mouseDown}, {
|
|
size = 18,
|
|
thickness = 2,
|
|
color = {0.9, 0.95, 1.0, 1.0},
|
|
activeColor = {1.0, 0.4, 0.2, 1.0},
|
|
})
|
|
else
|
|
Gui.cursor(ctx, input, {
|
|
size = 16,
|
|
thickness = 2,
|
|
color = {1.0, 0.9, 0.2, 1.0},
|
|
activeColor = {1.0, 0.35, 0.15, 1.0},
|
|
})
|
|
end
|
|
ctx:endFrame()
|
|
return ctx:getCommands()
|
|
end
|