// 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); }