#include "TableTemplate.hpp" bool TableCell::IsPrimaryCell() const { return PrimaryCellLocation == Location; } bool TableCell::IsMergedCell() const { return PrimaryCellLocation.x == -1 || PrimaryCellLocation.y == -1; } int TableTemplate::GetTableWidth() const { return mTableWidth; } int TableTemplate::GetTableHeight() const { return mTableHeight; } void TableTemplate::Resize(int newWidth, int newHeight) { // TODO this doesn't gracefully handle resizing to a smaller size which trims some merged cells std::vector cells; cells.reserve(newWidth * newHeight); int yEnd = std::min(mTableHeight, newHeight); int xEnd = std::min(mTableWidth, newWidth); for (int y = 0; y < yEnd; ++y) { if (y >= mTableHeight) { for (int x = 0; x < xEnd; ++x) { cells.push_back(TableCell{}); } continue; } for (int x = 0; x < xEnd; ++x) { if (x >= mTableWidth) { cells.push_back(TableCell{}); } else { auto& cell = GetCell({ x, y }); cells.push_back(std::move(cell)); } } } mCells = std::move(cells); } const TableCell& TableTemplate::GetCell(Vec2i pos) const { return mCells[pos.y * mTableWidth + pos.x]; } TableCell& TableTemplate::GetCell(Vec2i pos) { return const_cast(const_cast(this)->GetCell(pos)); } TableTemplate::MergeCellsResult TableTemplate::MergeCells(Vec2i topLeft, Vec2i bottomRight) { auto SortTwo = [](int& a, int& b) { if (a > b) { std::swap(a, b); } }; SortTwo(topLeft.x, bottomRight.x); SortTwo(topLeft.y, bottomRight.y); auto ResetProgress = [&]() { for (int y = topLeft.y; y < bottomRight.y; ++y) { for (int x = topLeft.x; x < bottomRight.x; ++x) { auto& cell = GetCell({ x, y }); cell.PrimaryCellLocation = { -1, -1 }; } } }; for (int y = topLeft.y; y < bottomRight.y; ++y) { for (int x = topLeft.x; x < bottomRight.x; ++x) { auto& cell = GetCell({ x, y }); if (cell.IsMergedCell()) { ResetProgress(); return MCR_CellAlreadyMerged; } cell.PrimaryCellLocation = topLeft; } } auto& primaryCell = GetCell(topLeft); primaryCell.SpanX = bottomRight.x - topLeft.x; primaryCell.SpanY = bottomRight.y - topLeft.y; return MCR_Success; } TableTemplate::BreakCellsResult TableTemplate::BreakCells(Vec2i topLeft) { auto& primaryCell = GetCell(topLeft); if (!primaryCell.IsMergedCell()) { return BCR_CellNotMerged; } for (int dy = 0; dy < primaryCell.SpanY; ++dy) { for (int dx = 0; dx < primaryCell.SpanX; ++dx) { auto& cell = GetCell({ topLeft.x + dx, topLeft.y + dy }); cell.PrimaryCellLocation = { -1, -1 }; } } primaryCell.SpanX = 1; primaryCell.SpanY = 1; return BCR_Success; }