Implement UIs using RmlUi
This commit is contained in:
parent
8039b1276e
commit
7f37be386d
27 changed files with 1457 additions and 42 deletions
124
src/rutile/core/ui/ui_server.cppm
Normal file
124
src/rutile/core/ui/ui_server.cppm
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
module;
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <RmlUi/Core.h>
|
||||
#include <RmlUi/Debugger.h>
|
||||
|
||||
export module rutile.core.ui.ui_server;
|
||||
|
||||
import rutile.core.ui.backend.rmlui_render_interface;
|
||||
import rutile.core.ui.backend.rmlui_system_interface;
|
||||
import rutile.core.ui.backend.rmlui_input_handler;
|
||||
import wrappers.sdl;
|
||||
|
||||
export namespace rutile
|
||||
{
|
||||
class UIServer
|
||||
{
|
||||
// Whether this class is currently instantiated (to prevent multiple instances because we need to do
|
||||
// Rml::Initialise() and Rml::Shutdown()).
|
||||
static bool instantiated_;
|
||||
|
||||
RmlUiSystemInterface system_interface_;
|
||||
RmlUiRenderInterface render_interface_;
|
||||
RmlUiInputHandler input_handler_;
|
||||
|
||||
// RmlUi context (non-owning pointer, lifetime managed by library)
|
||||
Rml::Context* context_;
|
||||
|
||||
public:
|
||||
explicit UIServer(sdl::Renderer& renderer, sdl::Window& window)
|
||||
: system_interface_{window},
|
||||
render_interface_{renderer},
|
||||
input_handler_{window}
|
||||
{
|
||||
// Prevent the class from being instantiated multiple times
|
||||
assert(!instantiated_);
|
||||
|
||||
Rml::SetSystemInterface(&system_interface_);
|
||||
Rml::SetRenderInterface(&render_interface_);
|
||||
Rml::Initialise();
|
||||
|
||||
// Create the main RmlUi context
|
||||
auto [window_width, window_height] = window.get_size();
|
||||
context_ = Rml::CreateContext("main", Rml::Vector2i(window_width, window_height));
|
||||
if (!context_) {
|
||||
throw std::runtime_error("RmlUi: Couldn't create context");
|
||||
}
|
||||
|
||||
// TODO: Implement some kind of switch to disable debugger (just use config::debug?)
|
||||
Rml::Debugger::Initialise(context_);
|
||||
|
||||
instantiated_ = true;
|
||||
}
|
||||
|
||||
// No copy or move operations
|
||||
UIServer(const UIServer&) = delete;
|
||||
UIServer& operator=(const UIServer&) = delete;
|
||||
UIServer(UIServer&&) = delete;
|
||||
UIServer& operator=(UIServer&&) = delete;
|
||||
|
||||
~UIServer()
|
||||
{
|
||||
Rml::Shutdown();
|
||||
instantiated_ = false;
|
||||
}
|
||||
|
||||
constexpr Rml::Context& get_context() const
|
||||
{
|
||||
// TODO: Can we assume context_ is always non-nullptr?
|
||||
assert(context_);
|
||||
return *context_;
|
||||
}
|
||||
|
||||
// Handles an SDL event. Returns true if the event has been handled.
|
||||
bool handle_event(const sdl::Event& event) const
|
||||
{
|
||||
// Toggle RmlUi debugger with F12
|
||||
if (event.type == sdl::EventTypes::KeyDown && event.key.key == sdl::Key::F12) {
|
||||
Rml::Debugger::SetVisible(!Rml::Debugger::IsVisible());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Let RmlUi handle relevant events
|
||||
if (input_handler_.handle_input_event(get_context(), event)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void update() const
|
||||
{
|
||||
get_context().Update();
|
||||
}
|
||||
|
||||
void render() const
|
||||
{
|
||||
render_interface_.prepare_render();
|
||||
get_context().Render();
|
||||
}
|
||||
|
||||
static void load_font_face(const std::string& file_path)
|
||||
{
|
||||
if (!Rml::LoadFontFace(file_path)) {
|
||||
throw std::runtime_error(std::format("RmlUi: Couldn't load font face \"{}\"", file_path));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Can/should we avoid the (non-owning) raw pointers here?
|
||||
Rml::ElementDocument* load_document(const std::string& file_path) const
|
||||
{
|
||||
Rml::ElementDocument* document = get_context().LoadDocument(file_path);
|
||||
|
||||
if (!document) {
|
||||
throw std::runtime_error(std::format("RmlUi: Couldn't load document \"{}\"", file_path));
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
};
|
||||
|
||||
bool UIServer::instantiated_ = false;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue