-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(tesseratos): add Menu Bar plugin
- Loading branch information
Showing
9 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |