128 lines
3.7 KiB
C++
128 lines
3.7 KiB
C++
// Copyright (c) 2023 Dominic Masters
|
|
//
|
|
// This software is released under the MIT License.
|
|
// https://opensource.org/licenses/MIT
|
|
|
|
#include "UISimpleMenu.hpp"
|
|
#include "game/DawnGame.hpp"
|
|
|
|
using namespace Dawn;
|
|
|
|
UISimpleMenu::UISimpleMenu(SceneItem *item) :
|
|
SceneItemComponent(item)
|
|
{
|
|
|
|
}
|
|
|
|
std::vector<SceneItemComponent*> UISimpleMenu::getDependencies() {
|
|
return {
|
|
(this->menu = this->item->getComponent<UIMenuController>()),
|
|
(this->canvas == nullptr ? (this->canvas = this->item->getComponent<UICanvas>()) : nullptr)
|
|
};
|
|
}
|
|
|
|
void UISimpleMenu::onStart() {
|
|
if(canvas == nullptr) canvas = getScene()->findComponent<UICanvas>();
|
|
|
|
assertNotNull(this->menu, "UISimpleMenu::onStart: Menu cannot be null");
|
|
assertNotNull(this->canvas, "UISimpleMenu::onStart: Canvas cannot be null");
|
|
menuItems = this->item->findChildren<UISimpleMenuItem>();
|
|
|
|
auto updateSimpleMenuPos = [&](int32_t x, int32_t y) {
|
|
if(currentlySelected != nullptr) {
|
|
currentlySelected->eventHoveredOff.invoke();
|
|
currentlySelected = nullptr;
|
|
}
|
|
|
|
// Find item
|
|
auto itItem = menuItems.begin();
|
|
while(itItem != menuItems.end()) {
|
|
auto itm = *itItem;
|
|
if(itm->menuX == x && itm->menuY == y) {
|
|
currentlySelected = itm;
|
|
break;
|
|
}
|
|
++itItem;
|
|
}
|
|
|
|
// Was anything found?
|
|
if(currentlySelected == nullptr) return;
|
|
currentlySelected->eventHoveredOn.invoke();
|
|
};
|
|
|
|
useEvent(updateSimpleMenuPos, menu->eventItemChange);
|
|
updateSimpleMenuPos(menu->menuX, menu->menuY);
|
|
|
|
useEvent([&](int32_t x, int32_t y){
|
|
if(currentlySelected == nullptr) return;
|
|
currentlySelected->eventSelected.invoke();
|
|
}, menu->eventItemSelected);
|
|
|
|
useEvent([&](float_t d){
|
|
assertNotNull(canvas->camera, "UISimpleMenu::onStart: Camera cannot be null");
|
|
if(!this->menu->active) return;
|
|
|
|
// Mouse in screen space.
|
|
auto mouse = getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y);
|
|
|
|
switch(canvas->drawType) {
|
|
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
|
case UI_DRAW_TYPE_WORLD_ABSOLUTE: {
|
|
|
|
// Calculate ray
|
|
struct Ray3D ray;
|
|
switch(canvas->drawType) {
|
|
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
|
|
mouse *= 2.0f;
|
|
mouse -= glm::vec2(1, 1);
|
|
ray.origin = canvas->camera->transform->getWorldPosition();
|
|
ray.direction = canvas->camera->getRayDirectionFromScreenSpace(mouse);
|
|
break;
|
|
|
|
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
|
auto rt = canvas->camera->getRenderTarget();
|
|
mouse *= glm::vec2(rt->getWidth(), rt->getHeight());
|
|
ray.origin = glm::vec3(mouse, 5);
|
|
ray.direction = glm::vec3(0, 0, -10);
|
|
break;
|
|
}
|
|
|
|
// Find mouse item
|
|
auto itItems = menuItems.begin();
|
|
while(itItems != menuItems.end()) {
|
|
auto item = *itItems;
|
|
++itItems;
|
|
auto highlight = item->getComponentForHighlighting();
|
|
if(highlight == nullptr) continue;
|
|
|
|
glm::vec2 size(
|
|
highlight->getContentWidth(),
|
|
highlight->getContentHeight()
|
|
);
|
|
glm::vec3 point;
|
|
glm::vec3 normal;
|
|
float_t distance;
|
|
|
|
// TODO: Include Z axis for determining which item is hovered.
|
|
if(!raytestQuad(
|
|
ray,
|
|
glm::vec2(0, 0), size,
|
|
highlight->transform->getWorldTransform(),
|
|
&point,
|
|
&normal,
|
|
&distance
|
|
)) continue;
|
|
|
|
this->menu->menuX = item->menuX;
|
|
this->menu->menuY = item->menuY;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
assertUnreachable("UISimpleMenu::onStart: Draw type not implemented");
|
|
}
|
|
}
|
|
}, getScene()->eventSceneUnpausedUpdate);
|
|
} |