#include "gridpreview.h" GridPreview::GridPreview(QWidget *parent) : QWidget{parent} {} void GridPreview::setSize(int newWidth, int newHeight) { width = newWidth; height = newHeight; emit updatedContents(); } void GridPreview::addLine(Line &line) { lines.push_back(line); emit updatedContents(); } void GridPreview::removeLine(int index) { lines.removeAt(index); emit updatedContents(); } void GridPreview::setLineColor(int index, const QString &color) { lines[index].setColor(color); emit updatedContents(); } void GridPreview::setLineStartPoint(int index, const QPoint &point) { lines[index].setStartPoint(point); emit updatedContents(); } void GridPreview::setLineEndPoint(int index, const QPoint &point) { lines[index].setEndPoint(point); emit updatedContents(); } void GridPreview::setColorMap(QMap &map) { colorMap = map; } int GridPreview::getWidth() { return width; } int GridPreview::getHeight() { return height; } const QList &GridPreview::getLines() const { return lines; } const Line &GridPreview::getLine(int index) const { return lines.at(index); } const PointProbe &GridPreview::getCapturedProbe() const { return capturedProbe; } PointProbe &GridPreview::getCapturedProbe() { return capturedProbe; } const QString GridPreview::toLuaTable() { QString output(tableTemplate.arg(width).arg(height)); QString linesSubTable = ""; for(auto iter = lines.begin(); iter != lines.end(); iter++ ) { linesSubTable += QString(" %1,\n").arg(iter->toLuaTable()); } linesSubTable.removeLast(); // \n linesSubTable.removeLast(); // , return output.arg(linesSubTable); } void GridPreview::paintEvent(QPaintEvent *) { QPainter painter(this); QPen pen(Qt::black, 2); painter.setPen(pen); QBrush brush(Qt::black); double aspectRatio = (double) rect().width() / rect().height(); double cellAspectRatio = (double) width / height; bool widthBased = aspectRatio > cellAspectRatio; int cellSize = widthBased ? rect().height() / height : rect().width() / width; int dotSize = cellSize * 0.5; int filledDotSize = cellSize * 0.7; int areaWidth = cellSize * width; int areaHeight = cellSize * height; int offsetX = (rect().width() - areaWidth) / 2; int offsetY = (rect().height() - areaHeight) / 2; QRect drawArea(offsetX, offsetY, areaWidth, areaHeight); // Draw main grid painter.drawRect(drawArea); QRect cell(0, 0, cellSize, cellSize); painter.setBrush(brush); for (int cellX = 0; cellX < width; cellX++) { for (int cellY = 0; cellY < height; cellY++) { cell.setLeft(offsetX + (cellSize - dotSize) / 2 + cellX * cellSize); cell.setWidth(dotSize); cell.setTop(offsetY + (cellSize - dotSize) / 2 + cellY * cellSize); cell.setHeight(dotSize); painter.drawEllipse(cell); } } // Draw line points for (auto iter = lines.begin(); iter < lines.end(); iter++) { QColor color(colorFromString(iter->getColor())); brush.setColor(color); painter.setBrush(brush); // Draw start cell.setLeft(offsetX + (cellSize - filledDotSize) / 2 + (iter->getStart().x() - 1) * cellSize); cell.setWidth(filledDotSize); cell.setTop(offsetY + (cellSize - filledDotSize) / 2 + (iter->getStart().y() - 1) * cellSize); cell.setHeight(filledDotSize); painter.drawEllipse(cell); // Draw end cell.setLeft(offsetX + (cellSize - filledDotSize) / 2 + (iter->getEnd().x() - 1) * cellSize); cell.setWidth(filledDotSize); cell.setTop(offsetY + (cellSize - filledDotSize) / 2 + (iter->getEnd().y() - 1) * cellSize); cell.setHeight(filledDotSize); painter.drawEllipse(cell); } } const QColor GridPreview::colorFromString(const QString color) { if (!colorMap.contains(color)) return colorMap[QString("red")]; return colorMap[color]; } void GridPreview::mouseMoveEvent(QMouseEvent *event) { if (!mouseCaptured) { return; } QPoint gridPos = localMousePosition(event); lastProbe = probePoint(gridPos); if (pointIsFree(lastProbe)) { if (capturedProbe.isStart) { setLineStartPoint(capturedProbe.ownerIndex, gridPos); } else { setLineEndPoint(capturedProbe.ownerIndex, gridPos); } } } void GridPreview::mousePressEvent(QMouseEvent *event) { mouseCaptured = true; QPoint gridPos = localMousePosition(event); std::cout << gridPos.x() << ',' << gridPos.y() << std::endl; lastProbe = probePoint(gridPos); capturedProbe = lastProbe; if (pointIsFree(lastProbe)) { Line line; line.setStartPoint(gridPos); line.setEndPoint(gridPos); addLine(line); capturedProbe.ownerIndex = lines.size() - 1; } emit updatedContents(); } void GridPreview::mouseReleaseEvent(QMouseEvent *event) { mouseCaptured = false; QPoint gridPos = localMousePosition(event); PointProbe probe = probePoint(gridPos); } const QPoint GridPreview::localMousePosition(QMouseEvent *event) { QPoint position(event->position().toPoint()); return snapToGrid(position); } const QPoint GridPreview::snapToGrid(const QPoint &global) { double aspectRatio = (double) rect().width() / rect().height(); double cellAspectRatio = (double) width / height; bool widthBased = aspectRatio > cellAspectRatio; int cellSize = widthBased ? rect().height() / height : rect().width() / width; int areaWidth = cellSize * width; int areaHeight = cellSize * height; int offsetX = (rect().width() - areaWidth) / 2; int offsetY = (rect().height() - areaHeight) / 2; return QPoint(1 + (global.x() - offsetX) / cellSize, 1 + (global.y() - offsetY) / cellSize); } bool GridPreview::isPointOccupied(const QPoint &point) { for (auto iter = lines.begin(); iter < lines.end(); iter++) { if (iter->getStart() == point || iter->getEnd() == point) { return true; } } return false; } bool GridPreview::pointInBounds(const QPoint &point) { return point.x() > 0 && point.y() > 0 && point.x() <= width && point.y() <= height; } bool GridPreview::pointIsFree(PointProbe& pp) { return pp.ownerIndex == -1 && pp.inBounds; } const PointProbe GridPreview::probePoint(const QPoint &point) { for (int i = 0; i < lines.size(); i++) { if (lines[i].getStart() == point || lines[i].getEnd() == point) { return PointProbe(i, lines[i].getStart() == point, pointInBounds(point)); } } return PointProbe(); }