ImGui
Using the ImGui integration plugin and cubos::
The ImGui plugin allows you to integrate the Dear ImGui library with Cubos, making it quick, straightforward, and effortless to create user interfaces and interactive debugging tools within your applications.
First, let's start by including the header files we need.
#include <iostream> #include <map> #include <vector> #include <imgui.h> #include <cubos/core/reflection/external/map.hpp> #include <cubos/core/reflection/external/primitives.hpp> #include <cubos/core/reflection/external/string.hpp> #include <cubos/core/reflection/external/vector.hpp> #include <cubos/core/reflection/reflect.hpp> #include <cubos/core/reflection/traits/constructible.hpp> #include <cubos/core/reflection/traits/fields.hpp> #include <cubos/core/reflection/traits/nullable.hpp> #include <cubos/engine/imgui/data_inspector.hpp> #include <cubos/engine/imgui/plugin.hpp> #include <cubos/engine/render/target/plugin.hpp> #include <cubos/engine/settings/plugin.hpp> #include <cubos/engine/window/plugin.hpp>
Then, make sure to add the plugin.
cubos.plugin(settingsPlugin); cubos.plugin(windowPlugin); cubos.plugin(renderTargetPlugin); cubos.plugin(imguiPlugin);
Once the ImGui plugin is added, you can create systems to display ImGui windows and widgets. Here's a system which opens an ImGui window, and its demo.
cubos.system("show ImGui demo").tagged(imguiTag).call([]() { ImGui::Begin("Dear ImGui + Cubos"); ImGui::Text("Hello world!"); ImGui::End(); ImGui::ShowDemoWindow(); });
Ensure that you add your system with the cubos.imgui
tag; otherwise, the ImGui elements from that system won't be be visible.
Pretty simple right? You're now equipped to craft and utilize ImGui's functions to design your cool user interface.
Now, we'll also show you how you can use the cubos::
To start off, we'll need to have some sort of dummy data shared across our application, so we can inspect/modify later. Let's create a DummyResource
with some fields and fill it with random data.
struct Person { CUBOS_REFLECT; std::string name; int32_t age; float weight; bool dead; }; CUBOS_REFLECT_IMPL(Person) { return Type::create("Person") .with(FieldsTrait() .withField("name", &Person::name) .withField("age", &Person::age) .withField("weight", &Person::weight) .withField("dead", &Person::dead)) .with(NullableTrait{[](const void* instance) { const auto* person = static_cast<const Person*>(instance); return person->dead; }, [](void* instance) { auto* person = static_cast<Person*>(instance); person->dead = true; }}) .with(ConstructibleTrait::typed<Person>().withDefaultConstructor().build()); } struct DummyResource { CUBOS_REFLECT; int integer; Person person; std::vector<Person> persons; std::vector<int32_t> vec; std::map<int32_t, int32_t> map; }; CUBOS_REFLECT_IMPL(DummyResource) { return Type::create("DummyResource") .with(FieldsTrait() .withField("integer", &DummyResource::integer) .withField("person", &DummyResource::person) .withField("persons", &DummyResource::persons) .withField("vec", &DummyResource::vec) .withField("v", &DummyResource::map)) .with(ConstructibleTrait::typed<DummyResource>().withDefaultConstructor().build()); }
cubos.resource<DummyResource>( DummyResource{.integer = 1337, .person = Person{"roby", 1337, 666.5F, false}, .persons{Person{"roby", 1337, 666.5F, false}, Person{"riscado", 123, 321.0F, false}}, .vec = {12, 59, 25}, .map = { {1, 2}, {2, 4}, {3, 6}, {4, 8}, }});
Well now, using the cubos::DataInspector::edit
and DataInspector::edit
.
cubos.system("data inspector example").tagged(imguiTag).call([](DataInspector& inspector, DummyResource& data) { ImGui::Begin("Data Inspector"); inspector.edit(data); ImGui::End(); });
You can find more about how to use Dear ImGui stuff here.