diff --git a/CMakeLists.txt b/CMakeLists.txt index 721eecf..2c3e710 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,37 +17,47 @@ add_library(lunasvg::lunasvg ALIAS PkgConfig::LUNASVG) find_package(RmlUi CONFIG REQUIRED) +add_library(rmlui_backend STATIC + vendor/rmlui_backend/RmlUi_Backend_SDL_GL3.cpp + vendor/rmlui_backend/RmlUi_Platform_SDL.cpp + vendor/rmlui_backend/RmlUi_Renderer_GL3.cpp +) + +target_include_directories(rmlui_backend PUBLIC + vendor/rmlui_backend +) + +target_compile_definitions(rmlui_backend PUBLIC + RMLUI_SDL_VERSION_MAJOR=3 + RMLUI_NUM_MSAA_SAMPLES=4 +) + +target_link_libraries(rmlui_backend PUBLIC + RmlUi::RmlUi + SDL3::SDL3 + SDL3_image::SDL3_image + Freetype::Freetype +) + add_executable(${PROJECT_NAME} - src/main.cpp - vendor/rmlui_backend/RmlUi_Platform_SDL.cpp - vendor/rmlui_backend/RmlUi_Renderer_GL3.cpp + src/main.cpp ) target_include_directories(${PROJECT_NAME} PRIVATE - src - vendor/rmlui_backend - ${FREETYPE_INCLUDE_DIRS} -) - -target_compile_definitions(${PROJECT_NAME} PRIVATE - RMLUI_SDL_VERSION_MAJOR=3 - RMLUI_NUM_MSAA_SAMPLES=4 + src ) target_link_libraries(${PROJECT_NAME} PRIVATE - RmlUi::RmlUi - RmlUi::Debugger - RmlUi::Lua - ${LUA_LIBRARIES} - Freetype::Freetype - lunasvg::lunasvg - SDL3::SDL3 - SDL3_image::SDL3_image + rmlui_backend + RmlUi::Debugger + RmlUi::Lua + ${LUA_LIBRARIES} + lunasvg::lunasvg ) install(TARGETS ${PROJECT_NAME} DESTINATION bin) install(DIRECTORY assets DESTINATION bin) target_compile_definitions(${PROJECT_NAME} PRIVATE - ASSETS_DIR="${CMAKE_SOURCE_DIR}/bin/assets" + ASSETS_DIR="${CMAKE_SOURCE_DIR}/bin/assets" ) diff --git a/assets/main.rml b/assets/main.rml new file mode 100644 index 0000000..bdfb0dd --- /dev/null +++ b/assets/main.rml @@ -0,0 +1,9 @@ + + + RmlShell + + + +

Hello world

+ +
diff --git a/assets/styles/main.rcss b/assets/styles/main.rcss new file mode 100644 index 0000000..71f511e --- /dev/null +++ b/assets/styles/main.rcss @@ -0,0 +1,270 @@ +/* ========================================================================== + RCSS User Agent Defaults (Plain HTML Style) + ========================================================================== */ + +/* Core Application Window Foundation */ +body { + display: block; + width: 100vw; + height: 100vh; + font-family: "rmlui-debugger-font"; + font-size: 16px; + background-color: #ffffff; + color: #000000; + margin: 0px; + padding: 0px; +} + +/* Generic Structural Layout Defaults */ +* { + box-sizing: border-box; +} + +div, section, article, header, footer, main, nav, aside { + display: block; +} + +span, em, strong, a { + display: inline; +} + +/* Typographic Defaults */ +p { + display: block; + margin: 1em 0px; +} + +h1, h2, h3, h4, h5, h6 { + display: block; + font-weight: bold; + margin: 0.83em 0px; +} + +h1 { font-size: 2em; } +h2 { font-size: 1.5em; } +h3 { font-size: 1.17em; } +h4 { font-size: 1em; } +h5 { font-size: 0.83em; } +h6 { font-size: 0.67em; } + +em { + font-style: italic; +} + +strong { + font-weight: bold; +} + +a { + color: #0000ee; + text-decoration: underline; +} + +a:hover { + color: #551a8b; +} + +blockquote { + display: block; + margin: 1em 40px; + padding-left: 10px; + border-left: 2px #cccccc; + color: #555555; +} + +code, pre { + font-family: "rmlui-debugger-font"; + background-color: #606060; + color: #000000; + padding: 3px; + font-style: italic; +} + +pre { + display: block; + white-space: pre; + margin: 1em 0px; + padding: 8px; +} + +/* Lists */ +ul, ol { + display: block; + margin: 1em 0px; + padding-left: 40px; +} + +li { + display: block; +} + +/* ========================================================================== + Tables + ========================================================================== */ +table { + display: table; +} + +tr { + display: table-row; +} + +td, th { + display: table-cell; + padding: 4px 8px; + text-align: left; +} + +th { + font-weight: bold; + background-color: #eaeaea; +} + +col { + display: table-column; +} + +colgroup { + display: table-column-group; +} + +thead, tbody, tfoot { + display: table-row-group; +} + +/* ========================================================================== + Form Inputs & Interactive UI Components + ========================================================================== */ +button, input, select, textarea { + display: inline-block; + font-family: "rmlui-debugger-font"; + font-size: 14px; + margin: 2px; + vertical-align: middle; +} + +/* Traditional gray bevel button style */ +button, input[type="submit"], input[type="button"] { + padding: 4px 12px; + min-width: 40px; + background-color: #e1e1e1; + color: #000000; + border: 1px #767676; + text-align: center; +} + +button:hover, input[type="submit"]:hover, input[type="button"]:hover { + background-color: #d0d0d0; + border: 1px #4f4f4f; +} + +button:active, input[type="submit"]:active, input[type="button"]:active { + background-color: #b5b5b5; + border: 1px #000000; +} + +/* Standard text field styling */ +input[type="text"], input[type="password"], textarea { + padding: 4px; + background-color: #ffffff; + color: #000000; + border: 1px #767676; +} + +input[type="text"]:focus, input[type="password"]:focus, textarea:focus { + border: 1px #005aff; +} + +textarea { + display: block; + white-space: pre-wrap; + width: 300px; + height: 100px; +} + +/* Select Box & Dropdowns */ +select { + padding: 4px; + background-color: #ffffff; + color: #000000; + border: 1px #767676; + text-align: left; +} + +/* ========================================================================== + RmlUi Specific Elements (Tabsets, Progress Bars, etc.) + ========================================================================== */ +tabset { + display: block; +} + +tabset tabs { + display: block; + border-bottom: 1px #cccccc; +} + +/* Simple default layout style for built-in tabs */ +tab { + display: inline-block; + padding: 6px 12px; + background-color: #f0f0f0; + border: 1px #cccccc; + margin-right: 2px; +} + +tab:selected { + background-color: #ffffff; + border-bottom: 1px #ffffff; /* Overlap the bottom border line */ + font-weight: bold; +} + +panel { + display: block; + padding: 10px; + background-color: #ffffff; +} + +/* Standard HTML5 / RmlUi Progress Bar Fallback */ +progress { + display: inline-block; + width: 160px; + height: 20px; + background-color: #e6e6e6; + border: 1px #b0b0b0; +} + +progress-value { + display: block; + height: 100%; + background-color: #0078d7; /* Classic Windows Blue fill */ +} + +/* ========================================================================== + Utility & Modern Layout Helpers + ========================================================================== */ +.flex { + display: flex; +} + +.flex-row { + flex-direction: row; +} + +.flex-col { + flex-direction: column; +} + +.justify-center { + justify-content: center; +} + +.align-center { + align-items: center; +} + +.hidden { + display: none; +} + + + diff --git a/src/main.cpp b/src/main.cpp index c3d3882..1173312 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,94 @@ +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include + + +static Rml::Context *ctx; + +bool f8_was_pressed = false; + +void handle_input() { + const bool *keystate = SDL_GetKeyboardState(nullptr); + + bool f8_state = keystate[SDL_SCANCODE_F8]; + if (f8_state && !f8_was_pressed) { + f8_was_pressed = true; + bool is_visible = Rml::Debugger::IsVisible(); + Rml::Debugger::SetVisible(!is_visible); + } else if (!f8_state) { + f8_was_pressed = false; + } +} + +std::string GetAssetsPath() { + std::string install_path = std::string(ASSETS_DIR) + "/main.rml"; + if (std::filesystem::exists(install_path)) { + return std::string(ASSETS_DIR); + } + if (std::filesystem::exists("./assets/main.rml")) { + return "./assets"; + } + return "."; +} + int main() { std::cout << "Hello world\n"; + + static std::string assets_path = std::string(ASSETS_DIR); + + if (!Backend::Initialize("RmlShell", 800, 800, true)) { + std::cout << "[ERROR] backend already initalized?\n"; + return 1; + } + + Rml::SetSystemInterface(Backend::GetSystemInterface()); + Rml::SetRenderInterface(Backend::GetRenderInterface()); + Rml::Initialise(); + Rml::Lua::Initialise(); + + ctx = Rml::CreateContext("main", Rml::Vector2i(800,800)); + if (!ctx) { + std::cout << "[ERROR] failed to create context"; + Rml::Shutdown(); + Backend::Shutdown(); + return 1; + } + + Rml::Debugger::Initialise(ctx); + + bool is_running = true; + + Rml::ElementDocument* document = ctx->LoadDocument(GetAssetsPath() + "/main.rml"); + if (!document) { + std::cout << "[ERROR] failed to load main.rml\n"; + } else { + document->Show(); + } + + while(is_running) { + is_running = Backend::ProcessEvents(ctx); + + handle_input(); + + ctx->Update(); + Backend::BeginFrame(); + ctx->Render(); + Backend::PresentFrame(); + } + + Rml::Shutdown(); + Backend::Shutdown(); + + return 0; }