Dawn/archive/ui/UIMenu.cpp
2023-03-05 12:58:59 -08:00

125 lines
3.0 KiB
C++

// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIMenu.hpp"
#include "game/DawnGame.hpp"
using namespace Dawn;
UIMenu::UIMenu(UICanvas *canvas, int32_t columns, int32_t rows) {
assertNotNull(canvas);
assertTrue(columns > 0);
assertTrue(rows > 0);
this->canvas = canvas;
this->rows = rows;
this->columns = columns;
this->items = (UIMenuItem**)memoryFillWithZero(sizeof(UIMenuItem*)*columns*rows);
}
void UIMenu::setSize(int32_t cols, int32_t rows) {
assertNotNull(this->items);
assertTrue(columns > 0);
assertTrue(rows > 0);
assertTrue(columns != this->columns);
assertTrue(rows != this->rows);
memoryFree(this->items);
this->items = (UIMenuItem**)memoryFillWithZero(sizeof(UIMenuItem*)*columns*rows);
}
UIMenuItem * UIMenu::getItem(int32_t x, int32_t y) {
return this->items[x * this->columns + y];
}
void UIMenu::setPosition(int32_t x, int32_t y) {
assertTrue(x >= 0 && x < this->columns);
assertTrue(y >= 0 && y < this->rows);
UIMenuItem *item;
if(this->x != -1) {
assertTrue(this->y != -1);
item = this->getItem(this->x, this->y);
if(item != nullptr) {
item->onItemOff();
}
}
this->eventCursorChange.invoke(this->x, this->y, x, y);
this->x = x;
this->y = y;
item = this->getItem(x, y);
if(item != nullptr && item->canBeOvered()) {
item->onItemOver();
}
}
void UIMenu::moveRelative(int32_t x, int32_t y) {
int32_t x2 = this->x + x;
if(x2 < 0 || x2 >= this->columns) return;
int32_t y2 = this->y + y;
if(y2 < 0 || y2 >= this->rows) return;
this->setPosition(x2, y2);
}
void UIMenu::setItem(int32_t x, int32_t y, UIMenuItem *item) {
assertTrue(x >= 0);
assertTrue(y >= 0);
assertTrue(x < this->columns);
assertTrue(y < this->rows);
assertNotNull(item);
assertNotNull(this->items);
assertNull(this->getItem(x, y));
this->items[x * this->columns + y] = item;
}
void UIMenu::onInactive() {
this->eventMenuInactive.invoke();
}
void UIMenu::onActive() {
this->eventMenuActive.invoke();
}
void UIMenu::onTick() {
auto im = &this->canvas->getGame()->inputManager;
if(im->isPressed(INPUT_BIND_ACCEPT)) {
auto item = this->getItem(this->x, this->y);
if(item != nullptr && item->canBeSelected()) {
item->onItemSelected();
return;
}
}
if(im->isPressed(INPUT_BIND_NEGATIVE_Y)) {
this->moveRelative(0, 1);
return;
}
if(im->isPressed(INPUT_BIND_POSITIVE_Y)) {
this->moveRelative(0, -1);
return;
}
if(im->isPressed(INPUT_BIND_NEGATIVE_X)) {
this->moveRelative(-1, 0);
return;
}
if(im->isPressed(INPUT_BIND_POSITIVE_X)) {
this->moveRelative(1, 0);
return;
}
// TODO: Support more modes and holding buttons to scroll.
}
UIMenu::~UIMenu() {
if(this->canvas->currentMenu == this) this->canvas->currentMenu = nullptr;
memoryFree(this->items);
}