UI menu now accepts mouse input from absolutes.
This commit is contained in:
@ -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)
|
@ -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.
|
||||
|
@ -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)();
|
||||
}
|
12
src/dawn/scene/components/ui/menu/CMakeLists.txt
Normal file
12
src/dawn/scene/components/ui/menu/CMakeLists.txt
Normal 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
|
||||
)
|
67
src/dawn/scene/components/ui/menu/UIMenuController.cpp
Normal file
67
src/dawn/scene/components/ui/menu/UIMenuController.cpp
Normal 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)();
|
||||
}
|
@ -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);
|
||||
|
110
src/dawn/scene/components/ui/menu/UISimpleMenu.cpp
Normal file
110
src/dawn/scene/components/ui/menu/UISimpleMenu.cpp
Normal 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);
|
||||
}
|
24
src/dawn/scene/components/ui/menu/UISimpleMenu.hpp
Normal file
24
src/dawn/scene/components/ui/menu/UISimpleMenu.hpp
Normal 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;
|
||||
};
|
||||
}
|
17
src/dawn/scene/components/ui/menu/UISimpleMenuItem.cpp
Normal file
17
src/dawn/scene/components/ui/menu/UISimpleMenuItem.cpp
Normal 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;
|
||||
}
|
25
src/dawn/scene/components/ui/menu/UISimpleMenuItem.hpp
Normal file
25
src/dawn/scene/components/ui/menu/UISimpleMenuItem.hpp
Normal 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();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user