add lua navigation
This commit is contained in:
122
main.cpp
122
main.cpp
@@ -9,12 +9,26 @@
|
||||
#include <RmlUi/Core.h>
|
||||
#include <RmlUi/Debugger.h>
|
||||
#include <RmlUi/Lua.h>
|
||||
#include <RmlUi/Lua/Interpreter.h>
|
||||
#include <RmlUi_Backend.h>
|
||||
#include <RmlUi_Include_Windows.h>
|
||||
#include <RmlUi_Include_GL3.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <png.h>
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
}
|
||||
|
||||
// Global app state for Lua access
|
||||
struct AppState {
|
||||
Rml::Context* context = nullptr;
|
||||
Rml::ElementDocument* document = nullptr;
|
||||
std::filesystem::path assets_path;
|
||||
} g_app;
|
||||
|
||||
void load_fonts(const std::filesystem::path& dir)
|
||||
{
|
||||
for (const auto& file : std::filesystem::directory_iterator(dir))
|
||||
@@ -26,6 +40,57 @@ void load_fonts(const std::filesystem::path& dir)
|
||||
}
|
||||
}
|
||||
|
||||
// Lua function: loadScreen(path) - loads a new RML document
|
||||
// Path is relative to assets folder
|
||||
int lua_loadScreen(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
|
||||
std::filesystem::path full_path = g_app.assets_path / path;
|
||||
|
||||
if (!std::filesystem::exists(full_path))
|
||||
{
|
||||
std::println("Screen not found: {}", full_path.string());
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Unload current document
|
||||
if (g_app.document)
|
||||
{
|
||||
g_app.context->UnloadDocument(g_app.document);
|
||||
g_app.document = nullptr;
|
||||
}
|
||||
|
||||
// Load new document
|
||||
g_app.document = g_app.context->LoadDocument(full_path.string());
|
||||
if (g_app.document)
|
||||
{
|
||||
g_app.document->Show();
|
||||
std::println("Loaded screen: {}", path);
|
||||
lua_pushboolean(L, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::println("Failed to load screen: {}", path);
|
||||
lua_pushboolean(L, false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Register custom Lua functions
|
||||
void registerLuaFunctions()
|
||||
{
|
||||
lua_State* L = Rml::Lua::Interpreter::GetLuaState();
|
||||
|
||||
// Register global function
|
||||
lua_pushcfunction(L, lua_loadScreen);
|
||||
lua_setglobal(L, "loadScreen");
|
||||
|
||||
std::println("Registered Lua functions");
|
||||
}
|
||||
|
||||
void DumpElementTree(Rml::Element* element, std::ofstream& out, int depth = 0)
|
||||
{
|
||||
if (!element) return;
|
||||
@@ -173,22 +238,25 @@ int main(const int argc, const char* argv[])
|
||||
Rml::Initialise();
|
||||
Rml::Lua::Initialise();
|
||||
|
||||
Rml::Context* context = Rml::CreateContext("main", Rml::Vector2i(window_width, window_height));
|
||||
if (!context)
|
||||
g_app.context = Rml::CreateContext("main", Rml::Vector2i(window_width, window_height));
|
||||
if (!g_app.context)
|
||||
{
|
||||
Rml::Shutdown();
|
||||
Backend::Shutdown();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Register custom Lua functions
|
||||
registerLuaFunctions();
|
||||
|
||||
// Find the assets folder by checking for fonts
|
||||
std::filesystem::path assets_path = std::filesystem::absolute(file.parent_path());
|
||||
g_app.assets_path = std::filesystem::absolute(file.parent_path());
|
||||
|
||||
// Walk up the directory tree to find a folder containing .ttf fonts
|
||||
while (!assets_path.empty() && assets_path.has_parent_path())
|
||||
while (!g_app.assets_path.empty() && g_app.assets_path.has_parent_path())
|
||||
{
|
||||
bool has_fonts = false;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(assets_path))
|
||||
for (const auto& entry : std::filesystem::directory_iterator(g_app.assets_path))
|
||||
{
|
||||
if (entry.path().extension() == ".ttf")
|
||||
{
|
||||
@@ -197,15 +265,15 @@ int main(const int argc, const char* argv[])
|
||||
}
|
||||
}
|
||||
if (has_fonts) break;
|
||||
assets_path = assets_path.parent_path();
|
||||
g_app.assets_path = g_app.assets_path.parent_path();
|
||||
}
|
||||
|
||||
load_fonts(assets_path);
|
||||
load_fonts(g_app.assets_path);
|
||||
|
||||
Rml::ElementDocument* document = context->LoadDocument(file.string());
|
||||
if (document)
|
||||
g_app.document = g_app.context->LoadDocument(file.string());
|
||||
if (g_app.document)
|
||||
{
|
||||
document->Show();
|
||||
g_app.document->Show();
|
||||
}
|
||||
|
||||
// Dump mode: render and capture screenshot
|
||||
@@ -222,10 +290,10 @@ int main(const int argc, const char* argv[])
|
||||
}
|
||||
|
||||
// First render to default framebuffer to initialize everything
|
||||
Backend::ProcessEvents(context);
|
||||
context->Update();
|
||||
Backend::ProcessEvents(g_app.context);
|
||||
g_app.context->Update();
|
||||
Backend::BeginFrame();
|
||||
context->Render();
|
||||
g_app.context->Render();
|
||||
Backend::PresentFrame();
|
||||
|
||||
// Create dump folder if it doesn't exist
|
||||
@@ -238,7 +306,7 @@ int main(const int argc, const char* argv[])
|
||||
{
|
||||
dump_file << "Window: " << window_width << "x" << window_height << "\n";
|
||||
dump_file << "\n=== Element Layout ===\n";
|
||||
DumpElementTree(document, dump_file);
|
||||
DumpElementTree(g_app.document, dump_file);
|
||||
dump_file.close();
|
||||
}
|
||||
|
||||
@@ -252,8 +320,8 @@ int main(const int argc, const char* argv[])
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Render to FBO
|
||||
context->Update();
|
||||
context->Render();
|
||||
g_app.context->Update();
|
||||
g_app.context->Render();
|
||||
|
||||
// Read pixels
|
||||
auto pixels = fbo.readPixels();
|
||||
@@ -269,7 +337,7 @@ int main(const int argc, const char* argv[])
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
const HANDLE hNotif = FindFirstChangeNotification(assets_path.c_str(),
|
||||
const HANDLE hNotif = FindFirstChangeNotification(g_app.assets_path.c_str(),
|
||||
TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE);
|
||||
|
||||
bool running = true;
|
||||
@@ -278,22 +346,22 @@ int main(const int argc, const char* argv[])
|
||||
if (const DWORD wait_result = WaitForSingleObject(hNotif, 100);
|
||||
wait_result == WAIT_OBJECT_0)
|
||||
{
|
||||
if (document)
|
||||
context->UnloadDocument(document);
|
||||
context->Update();
|
||||
if (g_app.document)
|
||||
g_app.context->UnloadDocument(g_app.document);
|
||||
g_app.context->Update();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
document = context->LoadDocument(file.string());
|
||||
if (document)
|
||||
g_app.document = g_app.context->LoadDocument(file.string());
|
||||
if (g_app.document)
|
||||
{
|
||||
document->ReloadStyleSheet();
|
||||
document->Show();
|
||||
g_app.document->ReloadStyleSheet();
|
||||
g_app.document->Show();
|
||||
}
|
||||
FindNextChangeNotification(hNotif);
|
||||
}
|
||||
running = Backend::ProcessEvents(context);
|
||||
context->Update();
|
||||
running = Backend::ProcessEvents(g_app.context);
|
||||
g_app.context->Update();
|
||||
Backend::BeginFrame();
|
||||
context->Render();
|
||||
g_app.context->Render();
|
||||
Backend::PresentFrame();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user