okay, menu map
This commit is contained in:
81
src/desktoplib/terminal/ui/MenuMap.cpp
Normal file
81
src/desktoplib/terminal/ui/MenuMap.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "MenuMap.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ckitty::terminal {
|
||||
|
||||
MenuMap::MenuMap(int width, int height)
|
||||
: _w(width), _h(height), _grid(width* height, 0) {
|
||||
}
|
||||
|
||||
void MenuMap::set(int x, int y, int id) {
|
||||
if (x >= 0 && x < _w && y >= 0 && y < _h) {
|
||||
_grid[y * _w + x] = id;
|
||||
}
|
||||
}
|
||||
|
||||
void MenuMap::fill(int x, int y, int w, int h, int id) {
|
||||
for (int i = y; i < y + h; ++i) {
|
||||
for (int j = x; j < x + w; ++j) {
|
||||
set(j, i, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MenuMap::get(int x, int y) const {
|
||||
if (x < 0 || x >= _w || y < 0 || y >= _h) return 0;
|
||||
return _grid[y * _w + x];
|
||||
}
|
||||
|
||||
void MenuMap::setWrap(bool x, bool y) {
|
||||
_wrapX = x; _wrapY = y;
|
||||
}
|
||||
|
||||
void MenuMap::setCursor(int x, int y) {
|
||||
_cursorX = std::clamp(x, 0, _w - 1);
|
||||
_cursorY = std::clamp(y, 0, _h - 1);
|
||||
}
|
||||
|
||||
MenuMap::Result MenuMap::getCursor() const {
|
||||
return { get(_cursorX, _cursorY), _cursorX, _cursorY };
|
||||
}
|
||||
|
||||
std::optional<MenuMap::Result> MenuMap::findNext(int dx, int dy) {
|
||||
int startX = _cursorX;
|
||||
int startY = _cursorY;
|
||||
int curX = _cursorX;
|
||||
int curY = _cursorY;
|
||||
|
||||
while (true) {
|
||||
curX += dx;
|
||||
curY += dy;
|
||||
|
||||
// Handle Wrap or Bounds
|
||||
if (_wrapX) {
|
||||
if (curX < 0) curX = _w - 1;
|
||||
else if (curX >= _w) curX = 0;
|
||||
} else if (curX < 0 || curX >= _w) return std::nullopt;
|
||||
|
||||
if (_wrapY) {
|
||||
if (curY < 0) curY = _h - 1;
|
||||
else if (curY >= _h) curY = 0;
|
||||
} else if (curY < 0 || curY >= _h) return std::nullopt;
|
||||
|
||||
// Check if we looped back to start (fail condition for wrap)
|
||||
if (curX == startX && curY == startY) return std::nullopt;
|
||||
|
||||
int val = get(curX, curY);
|
||||
if (val != 0 && val != get(startX, startY)) {
|
||||
_cursorX = curX;
|
||||
_cursorY = curY;
|
||||
return Result{ val, curX, curY };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<MenuMap::Result> MenuMap::moveUp() { return findNext(0, -1); }
|
||||
std::optional<MenuMap::Result> MenuMap::moveDown() { return findNext(0, 1); }
|
||||
std::optional<MenuMap::Result> MenuMap::moveLeft() { return findNext(-1, 0); }
|
||||
std::optional<MenuMap::Result> MenuMap::moveRight() { return findNext(1, 0); }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
namespace ckitty::terminal {
|
||||
|
||||
class MenuMap {
|
||||
public:
|
||||
|
||||
struct Result {
|
||||
int id;
|
||||
int x, y;
|
||||
};
|
||||
|
||||
private:
|
||||
int _w, _h;
|
||||
int _cursorX = 0;
|
||||
int _cursorY = 0;
|
||||
bool _wrapX = false;
|
||||
bool _wrapY = false;
|
||||
std::vector<int> _grid;
|
||||
|
||||
public:
|
||||
|
||||
MenuMap(int width, int height);
|
||||
|
||||
// Grid Management
|
||||
void set(int x, int y, int id);
|
||||
void fill(int x, int y, int w, int h, int id);
|
||||
int get(int x, int y) const;
|
||||
|
||||
// Configuration
|
||||
void setWrap(bool x, bool y);
|
||||
|
||||
// Navigation - Returns the new ID if movement was successful
|
||||
std::optional<Result> moveUp();
|
||||
std::optional<Result> moveDown();
|
||||
std::optional<Result> moveLeft();
|
||||
std::optional<Result> moveRight();
|
||||
|
||||
// Cursor Management
|
||||
void setCursor(int x, int y);
|
||||
Result getCursor() const;
|
||||
|
||||
private:
|
||||
|
||||
// The core search engine
|
||||
std::optional<Result> findNext(int dx, int dy);
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user