Add the UI demo: title menu, raw-CLAY options screen, HUD and dialog
examples/uidemo is the program the UI chapter quotes. Three screens, three
ways of building an interface: the title screen is one akgl_UiMenu plus a
heading label; the options screen is written in raw CLAY() declarations --
hover highlighting inside the declaration, clicks paired with the
application's own press edge -- because the widgets are a convenience, not a
boundary; and the play screen is two HUD labels and the one-call dialog over
a checkerboard standing in for a game world. No tilemap, no actors, no
physics: everything left on screen is the subject.
Its route_event() is the documented call-order contract in the flesh -- UI
first, consumed events stop there, then the current screen's keys -- and the
screen routing is the focus model, stated rather than invented.
The headless smoke run (example_uidemo, --frames 240 --demo) tours every
path through the real event chain: a mouse click on the centred menu (the
consumed path, landing on the middle row by symmetry), keyboard into and out
of the options screen, the dialog opened and dismissed, and Quit confirmed
from the menu. The run prints its score and settings so a pass can be read,
not just counted. docs_game_figures gains a uidemo frame -- the play screen
with the dialog up -- for the chapter to come.
Co-Authored-By: Claude Code (Claude Fable 5, claude-fable-5) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 11:24:58 -04:00
|
|
|
# The UI demo, quoted by the UI chapter's `c excerpt=` blocks.
|
|
|
|
|
#
|
|
|
|
|
# A real target built by `all`, on the same terms as the tutorial games: a
|
|
|
|
|
# chapter whose program does not compile is the failure the documentation
|
|
|
|
|
# harness exists to stop.
|
|
|
|
|
|
|
|
|
|
add_executable(uidemo
|
|
|
|
|
uidemo.c
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
target_link_libraries(uidemo
|
|
|
|
|
PRIVATE akstdlib::akstdlib akerror::akerror akgl
|
|
|
|
|
SDL3::SDL3 SDL3_ttf::SDL3_ttf SDL3_image::SDL3_image SDL3_mixer::SDL3_mixer
|
|
|
|
|
jansson::jansson -lm)
|
|
|
|
|
target_include_directories(uidemo PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
|
|
|
target_compile_options(uidemo PRIVATE ${AKGL_WARNING_FLAGS})
|
|
|
|
|
|
|
|
|
|
# The demo needs no art -- its "world" is akgl_draw_background -- but it does
|
|
|
|
|
# need one font, and it uses the same test-asset face the JRPG does, compiled
|
|
|
|
|
# in as an absolute path for the same run-from-anywhere reason.
|
|
|
|
|
get_filename_component(UIDEMO_REPO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
|
|
|
|
|
target_compile_definitions(uidemo PRIVATE
|
|
|
|
|
UIDEMO_FONT_FILE="${UIDEMO_REPO_ROOT}/tests/assets/akgl_test_mono.ttf"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if(AKGL_VENDORED_DEPENDENCIES)
|
|
|
|
|
set_target_properties(uidemo PROPERTIES BUILD_RPATH "${AKGL_VENDORED_RPATH}")
|
|
|
|
|
endif()
|
|
|
|
|
|
|
|
|
|
# The headless smoke run. `--demo` tours every screen through the real event
|
|
|
|
|
# chain -- a mouse click on the title menu (the consumed path), keyboard into
|
|
|
|
|
# and out of the raw-CLAY options screen, the play screen's dialog opened and
|
|
|
|
|
# dismissed, and Quit confirmed from the menu -- rather than just proving that
|
|
|
|
|
# main() returns. There is no physics here, so nothing needs a driven clock;
|
|
|
|
|
# `--frames` is a backstop above the script's last step, not the exit path.
|
|
|
|
|
add_test(NAME example_uidemo COMMAND uidemo --frames 240 --demo)
|
2026-08-02 14:19:05 -04:00
|
|
|
set_tests_properties(example_uidemo PROPERTIES TIMEOUT 120)
|
|
|
|
|
# set_property, not set_tests_properties: the latter parses its PROPERTIES
|
|
|
|
|
# arguments as name/value *pairs*, so a semicolon-separated value is split and
|
|
|
|
|
# every element after the first is consumed as a bogus property name. See the
|
|
|
|
|
# same note in the other examples' CMakeLists.
|
|
|
|
|
set_property(TEST example_uidemo PROPERTY ENVIRONMENT
|
|
|
|
|
"SDL_VIDEODRIVER=dummy"
|
|
|
|
|
"SDL_RENDER_DRIVER=software"
|
|
|
|
|
"SDL_AUDIODRIVER=dummy"
|
Add the UI demo: title menu, raw-CLAY options screen, HUD and dialog
examples/uidemo is the program the UI chapter quotes. Three screens, three
ways of building an interface: the title screen is one akgl_UiMenu plus a
heading label; the options screen is written in raw CLAY() declarations --
hover highlighting inside the declaration, clicks paired with the
application's own press edge -- because the widgets are a convenience, not a
boundary; and the play screen is two HUD labels and the one-call dialog over
a checkerboard standing in for a game world. No tilemap, no actors, no
physics: everything left on screen is the subject.
Its route_event() is the documented call-order contract in the flesh -- UI
first, consumed events stop there, then the current screen's keys -- and the
screen routing is the focus model, stated rather than invented.
The headless smoke run (example_uidemo, --frames 240 --demo) tours every
path through the real event chain: a mouse click on the centred menu (the
consumed path, landing on the middle row by symmetry), keyboard into and out
of the options screen, the dialog opened and dismissed, and Quit confirmed
from the menu. The run prints its score and settings so a pass can be read,
not just counted. docs_game_figures gains a uidemo frame -- the play screen
with the dialog up -- for the chapter to come.
Co-Authored-By: Claude Code (Claude Fable 5, claude-fable-5) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 11:24:58 -04:00
|
|
|
)
|
|
|
|
|
|
2026-08-02 14:19:05 -04:00
|
|
|
# LD_LIBRARY_PATH for the vendored satellite libraries. Only needed when they
|
|
|
|
|
# were vendored; an installed build resolves them normally.
|
Add the UI demo: title menu, raw-CLAY options screen, HUD and dialog
examples/uidemo is the program the UI chapter quotes. Three screens, three
ways of building an interface: the title screen is one akgl_UiMenu plus a
heading label; the options screen is written in raw CLAY() declarations --
hover highlighting inside the declaration, clicks paired with the
application's own press edge -- because the widgets are a convenience, not a
boundary; and the play screen is two HUD labels and the one-call dialog over
a checkerboard standing in for a game world. No tilemap, no actors, no
physics: everything left on screen is the subject.
Its route_event() is the documented call-order contract in the flesh -- UI
first, consumed events stop there, then the current screen's keys -- and the
screen routing is the focus model, stated rather than invented.
The headless smoke run (example_uidemo, --frames 240 --demo) tours every
path through the real event chain: a mouse click on the centred menu (the
consumed path, landing on the middle row by symmetry), keyboard into and out
of the options screen, the dialog opened and dismissed, and Quit confirmed
from the menu. The run prints its score and settings so a pass can be read,
not just counted. docs_game_figures gains a uidemo frame -- the play screen
with the dialog up -- for the chapter to come.
Co-Authored-By: Claude Code (Claude Fable 5, claude-fable-5) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 11:24:58 -04:00
|
|
|
if(AKGL_VENDORED_DEPENDENCIES)
|
|
|
|
|
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22")
|
|
|
|
|
set(UIDEMO_TEST_ENV_MOD "")
|
|
|
|
|
foreach(dir IN LISTS AKGL_TEST_LIBPATH)
|
|
|
|
|
list(APPEND UIDEMO_TEST_ENV_MOD "LD_LIBRARY_PATH=path_list_prepend:${dir}")
|
|
|
|
|
endforeach()
|
2026-08-02 14:19:05 -04:00
|
|
|
set_property(TEST example_uidemo PROPERTY ENVIRONMENT_MODIFICATION ${UIDEMO_TEST_ENV_MOD})
|
Add the UI demo: title menu, raw-CLAY options screen, HUD and dialog
examples/uidemo is the program the UI chapter quotes. Three screens, three
ways of building an interface: the title screen is one akgl_UiMenu plus a
heading label; the options screen is written in raw CLAY() declarations --
hover highlighting inside the declaration, clicks paired with the
application's own press edge -- because the widgets are a convenience, not a
boundary; and the play screen is two HUD labels and the one-call dialog over
a checkerboard standing in for a game world. No tilemap, no actors, no
physics: everything left on screen is the subject.
Its route_event() is the documented call-order contract in the flesh -- UI
first, consumed events stop there, then the current screen's keys -- and the
screen routing is the focus model, stated rather than invented.
The headless smoke run (example_uidemo, --frames 240 --demo) tours every
path through the real event chain: a mouse click on the centred menu (the
consumed path, landing on the middle row by symmetry), keyboard into and out
of the options screen, the dialog opened and dismissed, and Quit confirmed
from the menu. The run prints its score and settings so a pass can be read,
not just counted. docs_game_figures gains a uidemo frame -- the play screen
with the dialog up -- for the chapter to come.
Co-Authored-By: Claude Code (Claude Fable 5, claude-fable-5) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 11:24:58 -04:00
|
|
|
else()
|
|
|
|
|
string(REPLACE ";" ":" UIDEMO_TEST_LIBPATH_JOINED "${AKGL_TEST_LIBPATH}")
|
2026-08-02 14:19:05 -04:00
|
|
|
set_property(TEST example_uidemo APPEND PROPERTY ENVIRONMENT
|
|
|
|
|
"LD_LIBRARY_PATH=${UIDEMO_TEST_LIBPATH_JOINED}:$ENV{LD_LIBRARY_PATH}")
|
Add the UI demo: title menu, raw-CLAY options screen, HUD and dialog
examples/uidemo is the program the UI chapter quotes. Three screens, three
ways of building an interface: the title screen is one akgl_UiMenu plus a
heading label; the options screen is written in raw CLAY() declarations --
hover highlighting inside the declaration, clicks paired with the
application's own press edge -- because the widgets are a convenience, not a
boundary; and the play screen is two HUD labels and the one-call dialog over
a checkerboard standing in for a game world. No tilemap, no actors, no
physics: everything left on screen is the subject.
Its route_event() is the documented call-order contract in the flesh -- UI
first, consumed events stop there, then the current screen's keys -- and the
screen routing is the focus model, stated rather than invented.
The headless smoke run (example_uidemo, --frames 240 --demo) tours every
path through the real event chain: a mouse click on the centred menu (the
consumed path, landing on the middle row by symmetry), keyboard into and out
of the options screen, the dialog opened and dismissed, and Quit confirmed
from the menu. The run prints its score and settings so a pass can be read,
not just counted. docs_game_figures gains a uidemo frame -- the play screen
with the dialog up -- for the chapter to come.
Co-Authored-By: Claude Code (Claude Fable 5, claude-fable-5) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 11:24:58 -04:00
|
|
|
endif()
|
|
|
|
|
endif()
|