Skip to content

Commit

Permalink
feat(tesseratos): add Menu Bar plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
RiscadoA committed Jul 22, 2024
1 parent fedd0bf commit 9756791
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Image asset and UI Image component (#1270, **@DiogoMendonc-a**).
- Raycasting, collisions between rays and box/capsule colliders (#225, **@diogomsmiranda**).
- Change speed of the debug-camera using Tab and LShift, positive and negative respectively (#1159, **@diogomsmiranda**)
- A Menu Bar to Tesseratos (#1234, **@RiscadoA**).

### Changed

Expand Down
3 changes: 3 additions & 0 deletions tools/tesseratos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

set(TESSERATOS_SOURCE
"src/tesseratos/main.cpp"
"src/tesseratos/menu_bar/plugin.cpp"
"src/tesseratos/menu_bar/item.cpp"
"src/tesseratos/menu_bar/selected.cpp"
"src/tesseratos/asset_explorer/plugin.cpp"
"src/tesseratos/asset_explorer/popup.cpp"
"src/tesseratos/settings_inspector/plugin.cpp"
Expand Down
18 changes: 18 additions & 0 deletions tools/tesseratos/src/tesseratos/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <cubos/engine/input/plugin.hpp>
#include <cubos/engine/settings/plugin.hpp>
#include <cubos/engine/settings/settings.hpp>
#include <cubos/engine/transform/child_of.hpp>
#include <cubos/engine/utils/free_camera/plugin.hpp>

#include "asset_explorer/plugin.hpp"
Expand All @@ -12,6 +13,7 @@
#include "ecs_statistics/plugin.hpp"
#include "entity_inspector/plugin.hpp"
#include "entity_selector/plugin.hpp"
#include "menu_bar/plugin.hpp"
#include "metrics_panel/plugin.hpp"
#include "play_pause/plugin.hpp"
#include "scene_editor/plugin.hpp"
Expand Down Expand Up @@ -40,6 +42,7 @@ int main(int argc, char** argv)

cubos.plugin(toolboxPlugin);
cubos.plugin(entitySelectorPlugin);
cubos.plugin(menuBarPlugin);

cubos.plugin(assetExplorerPlugin);
cubos.plugin(entityInspectorPlugin);
Expand All @@ -66,5 +69,20 @@ int main(int argc, char** argv)
input.bind(*bindings);
});

cubos.startupSystem("add some menu items just for testing purposes").call([](Commands cmds) {
auto project = cmds.create().add(MenuBarItem{"Project", 0}).entity();
auto view = cmds.create().add(MenuBarItem{"View", 1}).entity();
cmds.create().add(MenuBarItem{"Help", 2});

cmds.create().add(MenuBarItem{"New", 0}).relatedTo(project, ChildOf{});
cmds.create().add(MenuBarItem{"Open", 1}).relatedTo(project, ChildOf{});
cmds.create().add(MenuBarItem{"Save", 2}).relatedTo(project, ChildOf{});

cmds.create().add(MenuBarItem{"Console", 0}).relatedTo(view, ChildOf{});
cmds.create().add(MenuBarItem{"Assets Explorer", 1}).relatedTo(view, ChildOf{});
cmds.create().add(MenuBarItem{"Entity Inspector", 2}).relatedTo(view, ChildOf{});
cmds.create().add(MenuBarItem{"World Inspector", 3}).relatedTo(view, ChildOf{});
});

cubos.run();
}
13 changes: 13 additions & 0 deletions tools/tesseratos/src/tesseratos/menu_bar/item.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "item.hpp"

#include <cubos/core/ecs/reflection.hpp>
#include <cubos/core/reflection/external/primitives.hpp>
#include <cubos/core/reflection/external/string.hpp>

CUBOS_REFLECT_IMPL(tesseratos::MenuBarItem)
{
return cubos::core::ecs::TypeBuilder<MenuBarItem>("tesseratos::MenuBarItem")
.withField("name", &MenuBarItem::name)
.withField("order", &MenuBarItem::order)
.build();
}
30 changes: 30 additions & 0 deletions tools/tesseratos/src/tesseratos/menu_bar/item.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/// @file
/// @brief Component @ref tesseratos::MenuBarItem.
/// @ingroup tesseratos-menu-bar-plugin

#pragma once

#include <string>

#include <cubos/core/reflection/reflect.hpp>

namespace tesseratos
{
/// @brief Component representing a menu bar item.
///
/// Adds an item to the menu bar at the top of the screen.
///
/// @ingroup tesseratos-menu-bar-plugin
struct MenuBarItem
{
CUBOS_REFLECT;

/// @brief Item name.
std::string name{"unnamed"};

/// @brief Item order priority, lower values are displayed first.
///
/// Ties are broken by the item's alphabetical order.
int order{0};
};
} // namespace tesseratos
102 changes: 102 additions & 0 deletions tools/tesseratos/src/tesseratos/menu_bar/plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "plugin.hpp"
#include <algorithm>

#include <imgui.h>

#include <cubos/engine/imgui/plugin.hpp>
#include <cubos/engine/transform/plugin.hpp>

using cubos::core::ecs::Traversal;
using namespace cubos::engine;
using namespace tesseratos;

namespace
{
struct Item
{
Entity entity;
MenuBarItem item;
std::vector<Item> items;
};
} // namespace

static void getChildItems(Item& parent, Query<Entity, const MenuBarItem&> childOf)
{
for (auto [entity, item] : childOf.pin(1, parent.entity))
{
Item child{entity, item, {}};
getChildItems(child, childOf);
parent.items.emplace_back(child);
}

std::sort(parent.items.begin(), parent.items.end(), [](const Item& a, const Item& b) {
return a.item.order < b.item.order || (a.item.order == b.item.order && a.item.name < b.item.name);
});
}

static void showItem(Commands& cmds, const Item& item)
{
if (item.items.empty())
{
if (ImGui::MenuItem(item.item.name.c_str()))
{
// Trigger any observers of the selected item.
cmds.add(item.entity, MenuBarSelected{});
cmds.remove<MenuBarSelected>(item.entity);
}
}
else
{
if (ImGui::BeginMenu(item.item.name.c_str()))
{
for (auto& child : item.items)
{
showItem(cmds, child);
}
ImGui::EndMenu();
}
}
}

void tesseratos::menuBarPlugin(Cubos& cubos)
{
cubos.depends(imguiPlugin);
cubos.depends(transformPlugin);

cubos.component<MenuBarItem>();
cubos.component<MenuBarSelected>();

cubos.system("draw MenuBar")
.tagged(imguiTag)
.with<MenuBarItem>()
.related<ChildOf>()
.call([](Commands cmds, Query<Entity, const MenuBarItem&> childOf, Query<Entity, const MenuBarItem&> items) {
if (!ImGui::BeginMainMenuBar())
{
return;
}

// Extract item tree from the queries, sorted by the order and name item fields.
std::vector<Item> processed{};
for (auto [entity, item] : items)
{
if (childOf.pin(0, entity).empty())
{
Item root{entity, item, {}};
getChildItems(root, childOf);
processed.push_back(root);
}
}
std::sort(processed.begin(), processed.end(), [](const Item& a, const Item& b) {
return a.item.order < b.item.order || (a.item.order == b.item.order && a.item.name < b.item.name);
});

// Show the menu bar.
for (const auto& item : processed)
{
showItem(cmds, item);
}

ImGui::EndMainMenuBar();
});
}
25 changes: 25 additions & 0 deletions tools/tesseratos/src/tesseratos/menu_bar/plugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/// @dir
/// @brief @ref tesseratos-menu-bar-plugin plugin directory.

/// @file
/// @brief Plugin entry point.
/// @ingroup tesseratos-menu-bar-plugin

#pragma once

#include <cubos/engine/prelude.hpp>

#include "item.hpp"
#include "selected.hpp"

namespace tesseratos
{
/// @defgroup tesseratos-menu-bar-plugin Menu Bar
/// @ingroup tesseratos
/// @brief Adds the @ref MenuBarItem and @ref MenuBarSelected components.

/// @brief Plugin entry function.
/// @param cubos @b Cubos main class
/// @ingroup tesseratos-game-plugin
void menuBarPlugin(cubos::engine::Cubos& cubos);
} // namespace tesseratos
8 changes: 8 additions & 0 deletions tools/tesseratos/src/tesseratos/menu_bar/selected.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "selected.hpp"

#include <cubos/core/ecs/reflection.hpp>

CUBOS_REFLECT_IMPL(tesseratos::MenuBarSelected)
{
return cubos::core::ecs::TypeBuilder<MenuBarSelected>("tesseratos::MenuBarSelected").build();
}
17 changes: 17 additions & 0 deletions tools/tesseratos/src/tesseratos/menu_bar/selected.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/// @file
/// @brief Component @ref tesseratos::MenuBarSelected.
/// @ingroup tesseratos-menu-bar-plugin

#pragma once

#include <cubos/core/reflection/reflect.hpp>

namespace tesseratos
{
/// @brief Component added to menu bar items when they are selected.
/// @ingroup tesseratos-menu-bar-plugin
struct MenuBarSelected
{
CUBOS_REFLECT;
};
} // namespace tesseratos

0 comments on commit 9756791

Please sign in to comment.