UI menu now accepts mouse input from absolutes.

This commit is contained in:
2023-03-08 16:39:24 -08:00
parent 95e5aa1eeb
commit 186ac8bc3f
20 changed files with 864 additions and 549 deletions

View File

@ -9,7 +9,6 @@ target_sources(${DAWN_TARGET_NAME}
UICanvas.cpp
UIComponent.cpp
UILabel.cpp
UIMenuController.cpp
)
tool_scenecomponent(UICanvas scene/components/ui/UICanvas.hpp)
add_subdirectory(menu)

View File

@ -64,7 +64,7 @@ namespace Dawn {
//======================================================================//
StateProperty<Camera*> camera;
enum UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;
enum UIDrawType drawType = UI_DRAW_TYPE_WORLD_ABSOLUTE;
/**
* Constructs the UI Canvas Scene Item Component.

View File

@ -1,30 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIMenuController.hpp"
using namespace Dawn;
UIMenuController::UIMenuController(SceneItem *item) :
SceneItemComponent(item),
active(false),
menuX(0),
menuY(0),
columns(4),
rows(4)
{
}
void UIMenuController::onStart() {
useEffectWithTeardown([&]{
if(!active) return activeTeardown = [&]{ };
return activeTeardown = [&]{
};
}, active)();
}

View File

@ -0,0 +1,12 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
UIMenuController.cpp
UISimpleMenu.cpp
UISimpleMenuItem.cpp
)

View File

@ -0,0 +1,67 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIMenuController.hpp"
#include "game/DawnGame.hpp"
using namespace Dawn;
UIMenuController::UIMenuController(SceneItem *item) :
SceneItemComponent(item),
active(true),
menuX(0),
menuY(0),
columns(4),
rows(4)
{
}
void UIMenuController::onStart() {
useEffectWithTeardown([&]{
if(!active) return activeTeardown = [&]{ };
useEffect([&]{
eventItemChange.invoke(menuX, menuY);
}, menuX);
useEffect([&]{
eventItemChange.invoke(menuX, menuY);
}, menuY);
useEffect([&]{
menuX = mathClamp<int32_t>(menuX, 0, rows);
}, columns);
useEffect([&]{
menuY = mathClamp<int32_t>(menuY, 0, rows);
}, rows);
return activeTeardown = useEvent([&](inputbind_t bind) {
switch(bind) {
case INPUT_BIND_POSITIVE_X:
menuX = mathClamp<int32_t>(menuX+1, 0, columns);
break;
case INPUT_BIND_POSITIVE_Y:
menuY = mathClamp<int32_t>(menuY+1, 0, rows);
break;
case INPUT_BIND_NEGATIVE_X:
menuX = mathClamp<int32_t>(menuX-1, 0, columns);
break;
case INPUT_BIND_NEGATIVE_Y:
menuY = mathClamp<int32_t>(menuY-1, 0, rows);
break;
case INPUT_BIND_ACCEPT:
eventItemSelected.invoke(menuX, menuY);
break;
case INPUT_BIND_CANCEL:
eventMenuCancel.invoke();
break;
default:
return;
}
}, this->getGame()->inputManager.eventBindPressed);
}, active)();
}

View File

@ -20,6 +20,9 @@ namespace Dawn {
StateEvent<int32_t, int32_t> eventItemChange;
StateEvent<int32_t, int32_t> eventItemSelected;
StateEvent<> eventMenuCancel;
void moveRelative(int32_t x, int32_t y);
UIMenuController(SceneItem *item);

View File

@ -0,0 +1,110 @@
// 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);
assertNotNull(this->canvas);
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);
if(!this->menu->active) return;
auto mouse = getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y);
mouse *= 2.0f;
mouse -= glm::vec2(1, 1);
struct Ray3D ray;
ray.origin = canvas->camera->transform->getWorldPosition();
ray.direction = canvas->camera->getRayDirectionFromScreenSpace(mouse);
switch(canvas->drawType) {
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
break;
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
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.
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;
}
}, getScene()->eventSceneUnpausedUpdate);
}

View File

@ -0,0 +1,24 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIMenuController.hpp"
#include "UISimpleMenuItem.hpp"
namespace Dawn {
class UISimpleMenu : public SceneItemComponent {
protected:
UIMenuController *menu = nullptr;
UICanvas *canvas = nullptr;
UISimpleMenuItem *currentlySelected = nullptr;
std::vector<UISimpleMenuItem*> menuItems;
public:
UISimpleMenu(SceneItem *item);
std::vector<SceneItemComponent*> getDependencies() override;
void onStart() override;
};
}

View File

@ -0,0 +1,17 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UISimpleMenuItem.hpp"
using namespace Dawn;
UISimpleMenuItem::UISimpleMenuItem(SceneItem *item) : SceneItemComponent(item) {
}
UIComponent * UISimpleMenuItem::getComponentForHighlighting() {
if(uiComponent == nullptr) uiComponent = item->getComponent<UIComponent>();
return uiComponent;
}

View File

@ -0,0 +1,25 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/components/ui/UIComponent.hpp"
namespace Dawn {
class UISimpleMenuItem : public SceneItemComponent {
public:
StateEvent<> eventHoveredOn;
StateEvent<> eventHoveredOff;
StateEvent<> eventSelected;
// May make these into either state events or make a new event.
int32_t menuX;
int32_t menuY;
UIComponent *uiComponent = nullptr;
UISimpleMenuItem(SceneItem *item);
virtual UIComponent * getComponentForHighlighting();
};
}