diff --git a/client/src/board/boardareawidget.cpp b/client/src/board/boardareawidget.cpp index f5c76f4e..f1430c04 100644 --- a/client/src/board/boardareawidget.cpp +++ b/client/src/board/boardareawidget.cpp @@ -27,7 +27,7 @@ #include #include #include "boardwidget.hpp" -#include "tile.hpp" +#include "tilepainter.hpp" #include "../network/board.hpp" #include "../network/abstractproperty.hpp" #include "../utils/rectf.hpp" @@ -42,9 +42,9 @@ QRect rectToViewport(const QRect& r, const int gridSize) return viewport; } -constexpr QRect tileRect(const int x, const int y, const int tileSize) +constexpr QRectF tileRect(const TileLocation l, const int w, const int h, const int tileSize) { - return QRect{x * (tileSize - 1), y * (tileSize - 1), tileSize, tileSize}; + return QRectF(l.x * (tileSize - 1), l.y * (tileSize - 1), 1 + w * (tileSize - 1), 1 + h * (tileSize - 1)); } @@ -52,7 +52,9 @@ BoardAreaWidget::BoardAreaWidget(BoardWidget& board, QWidget* parent) : QWidget(parent), m_board{board}, m_grid{Grid::Dot}, - m_zoomLevel{0} + m_zoomLevel{0}, + m_mouseMoveTileId{TileId::None}, + m_mouseMoveTileRotate{TileRotate::Deg0} { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setFocusPolicy(Qt::StrongFocus); @@ -99,6 +101,22 @@ void BoardAreaWidget::setZoomLevel(int value) } } +void BoardAreaWidget::setMouseMoveTileId(TileId id) +{ + if(m_mouseMoveTileId == id) + return; + m_mouseMoveTileId = id; + update(); +} + +void BoardAreaWidget::setMouseMoveTileRotate(TileRotate rotate) +{ + if(m_mouseMoveTileRotate == rotate) + return; + m_mouseMoveTileRotate = rotate; + update(); +} + TurnoutPosition BoardAreaWidget::getTurnoutPosition(const TileLocation& l) const { if(ObjectPtr object = m_board.board().getTileObject(l)) @@ -160,7 +178,7 @@ void BoardAreaWidget::mouseReleaseEvent(QMouseEvent* event) else if(m_mouseRightButtonPressed && event->button() == Qt::RightButton) { m_mouseRightButtonPressed = false; - if((event->pos() - m_mouseRightButtonPressedPoint).manhattanLength() < 5) + if((event->pos() - m_mouseRightButtonPressedPoint).manhattanLength() < 5 || m_mouseMoveTileId != TileId::None) emit rightClicked(); } } @@ -174,6 +192,8 @@ void BoardAreaWidget::mouseMoveEvent(QMouseEvent* event) { m_mouseMoveTileLocation = tl; emit mouseTileLocationChanged(tl.x, tl.y); + if(m_mouseMoveTileId != TileId::None) + update(); } } QWidget::mouseMoveEvent(event); @@ -196,8 +216,9 @@ void BoardAreaWidget::wheelEvent(QWheelEvent* event) void BoardAreaWidget::paintEvent(QPaintEvent* event) { const QColor backgroundColor{0x10, 0x10, 0x10}; + const QColor backgroundColor50{0x10, 0x10, 0x10, 0x80}; const QColor gridColor{0x40, 0x40, 0x40}; - const QColor trackColor{0xC0, 0xC0, 0xC0}; + const QColor gridColorHighlight{Qt::white}; const int tileSize = getTileSize(); const int gridSize = tileSize - 1; @@ -236,6 +257,8 @@ void BoardAreaWidget::paintEvent(QPaintEvent* event) const QRect tiles{viewport.left() / gridSize, viewport.top() / gridSize, viewport.width() / gridSize, viewport.height() / gridSize}; + painter.save(); + for(auto it : m_board.board().tileData()) if(it.first.x + it.second.width() - 1 >= tiles.left() && it.first.x <= tiles.right() && it.first.y + it.second.height() - 1 >= tiles.top() && it.first.y <= tiles.bottom()) @@ -287,4 +310,15 @@ void BoardAreaWidget::paintEvent(QPaintEvent* event) break; } } + + painter.restore(); + + if(m_mouseMoveTileId != TileId::None) + { + const QRectF r = tileRect(m_mouseMoveTileLocation, 1, 1, tileSize); + painter.fillRect(r, backgroundColor50); + painter.setPen(gridColorHighlight); + painter.drawRect(r.adjusted(-0.5, -0.5, 0.5, 0.5)); + tilePainter.draw(m_mouseMoveTileId, r, m_mouseMoveTileRotate); + } } diff --git a/client/src/board/boardareawidget.hpp b/client/src/board/boardareawidget.hpp index 8df9e50a..00a0c089 100644 --- a/client/src/board/boardareawidget.hpp +++ b/client/src/board/boardareawidget.hpp @@ -24,7 +24,9 @@ #define TRAINTASTIC_CLIENT_BOARD_BOARDAREAWIDGET_HPP #include +#include #include +#include #include #include @@ -52,7 +54,9 @@ class BoardAreaWidget : public QWidget bool m_mouseRightButtonPressed; QPoint m_mouseRightButtonPressedPoint; + TileId m_mouseMoveTileId; TileLocation m_mouseMoveTileLocation; + TileRotate m_mouseMoveTileRotate; int getTileSize() const { return 25 + m_zoomLevel * 5; } TurnoutPosition getTurnoutPosition(const TileLocation& l) const; @@ -76,6 +80,9 @@ class BoardAreaWidget : public QWidget void nextGrid(); int zoomLevel() const { return m_zoomLevel; } + void setMouseMoveTileId(TileId id); + void setMouseMoveTileRotate(TileRotate rotate); + public slots: void setGrid(Grid value); void setZoomLevel(int value); diff --git a/client/src/board/boardwidget.cpp b/client/src/board/boardwidget.cpp index cb268005..8a7e35c1 100644 --- a/client/src/board/boardwidget.cpp +++ b/client/src/board/boardwidget.cpp @@ -42,36 +42,36 @@ struct TileInfo { QString classId; + TileId id; uint8_t rotates; }; -const std::array tileInfo = { - TileInfo{QStringLiteral("board_tile.rail.straight"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.buffer_stop"), 0xFF}, - TileInfo{QStringLiteral(""), 0}, - TileInfo{QStringLiteral("board_tile.rail.curve_45"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.curve_90"), 0xFF}, - TileInfo{QStringLiteral(""), 0}, - TileInfo{QStringLiteral("board_tile.rail.cross_45"), 0x03}, - TileInfo{QStringLiteral("board_tile.rail.cross_90"), 0x03}, - TileInfo{QStringLiteral(""), 0}, - TileInfo{QStringLiteral("board_tile.rail.turnout_left_45"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_left_90"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_left_curved"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_right_45"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_right_90"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_right_curved"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_wye"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_3way"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_singleslip"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.turnout_doubleslip"), 0xFF}, - TileInfo{QStringLiteral(""), 0}, - TileInfo{QStringLiteral("board_tile.rail.block"), 0x05}, - TileInfo{QStringLiteral("board_tile.rail.sensor"), 0xFF}, - TileInfo{QStringLiteral(""), 0}, - TileInfo{QStringLiteral("board_tile.rail.signal_2_aspect"), 0xFF}, - TileInfo{QStringLiteral("board_tile.rail.signal_3_aspect"), 0xFF}, - TileInfo{QStringLiteral(""), 0} +const std::array tileInfo = { + TileInfo{QStringLiteral("board_tile.rail.straight"), TileId::RailStraight, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.buffer_stop"), TileId::RailBufferStop, 0xFF}, + TileInfo{QStringLiteral(""), TileId::None, 0}, + TileInfo{QStringLiteral("board_tile.rail.curve_45"), TileId::RailCurve45, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.curve_90"), TileId::RailCurve90, 0xFF}, + TileInfo{QStringLiteral(""), TileId::None, 0}, + TileInfo{QStringLiteral("board_tile.rail.cross_45"), TileId::RailCross45, 0x03}, + TileInfo{QStringLiteral("board_tile.rail.cross_90"), TileId::RailCross90, 0x03}, + TileInfo{QStringLiteral(""), TileId::None, 0}, + TileInfo{QStringLiteral("board_tile.rail.turnout_left_45"), TileId::RailTurnoutLeft45, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_left_90"), TileId::RailTurnoutLeft90, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_left_curved"), TileId::RailTurnoutLeftCurved, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_right_45"), TileId::RailTurnoutRight45, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_right_90"), TileId::RailTurnoutRight90, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_right_curved"), TileId::RailTurnoutRightCurved, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_wye"), TileId::RailTurnoutWye, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_3way"), TileId::RailTurnout3Way, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_singleslip"), TileId::RailTurnoutSingleSlip, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.turnout_doubleslip"), TileId::RailTurnoutDoubleSlip, 0xFF}, + TileInfo{QStringLiteral(""), TileId::None, 0}, + TileInfo{QStringLiteral("board_tile.rail.block"), TileId::RailBlock, 0x05}, + TileInfo{QStringLiteral("board_tile.rail.sensor"), TileId::RailSensor, 0xFF}, + TileInfo{QStringLiteral(""), TileId::None, 0}, + TileInfo{QStringLiteral("board_tile.rail.signal_2_aspect"), TileId::RailSignal2Aspect, 0xFF}, + TileInfo{QStringLiteral("board_tile.rail.signal_3_aspect"), TileId::RailSignal3Aspect, 0xFF} }; inline void validRotate(TileRotate& rotate, uint8_t rotates) @@ -149,16 +149,28 @@ BoardWidget::BoardWidget(std::shared_ptr object, QWidget* parent) : m_editActions->setExclusive(true); - m_editActionNone = m_editActions->addAction(m_toolbarEdit->addAction(Theme::getIcon("mouse"), "")); + m_editActionNone = m_editActions->addAction(m_toolbarEdit->addAction(Theme::getIcon("mouse"), "", this, + [this]() + { + actionSelected(nullptr); + })); m_editActionNone->setCheckable(true); m_editActionNone->setData(-1); - m_editActionMove = m_editActions->addAction(m_toolbarEdit->addAction(Theme::getIcon("move_tile"), Locale::tr("board:move_tile"))); + m_editActionMove = m_editActions->addAction(m_toolbarEdit->addAction(Theme::getIcon("move_tile"), Locale::tr("board:move_tile"), this, + [this]() + { + actionSelected(nullptr); + })); m_editActionMove->setCheckable(true); m_editActionMove->setData(-1); m_editActionMove->setEnabled(false); // todo: implement - m_editActionDelete = m_editActions->addAction(m_toolbarEdit->addAction(Theme::getIcon("delete"), Locale::tr("board:delete_tile"))); + m_editActionDelete = m_editActions->addAction(m_toolbarEdit->addAction(Theme::getIcon("delete"), Locale::tr("board:delete_tile"), this, + [this]() + { + actionSelected(nullptr); + })); m_editActionDelete->setCheckable(true); m_editActionDelete->setData(-1); @@ -179,7 +191,7 @@ BoardWidget::BoardWidget(std::shared_ptr object, QWidget* parent) : connect(actions[0], &QAction::triggered, this, [this, action=actions[0]]() { - validRotate(m_editRotate, tileInfo[action->data().toInt()].rotates); + actionSelected(&tileInfo[action->data().toInt()]); }); } else // > 1 @@ -198,7 +210,7 @@ BoardWidget::BoardWidget(std::shared_ptr object, QWidget* parent) : action->setText(subAction->text()); action->setData(subAction->data()); action->setChecked(true); - validRotate(m_editRotate, tileInfo[subAction->data().toInt()].rotates); + actionSelected(&tileInfo[subAction->data().toInt()]); }); } action->setIcon(actions[0]->icon()); @@ -206,6 +218,11 @@ BoardWidget::BoardWidget(std::shared_ptr object, QWidget* parent) : action->setData(actions[0]->data()); action->setMenu(m); action->setCheckable(true); + connect(action, &QAction::triggered, this, + [this, action]() + { + actionSelected(&tileInfo[action->data().toInt()]); + }); } actions.clear(); } @@ -348,5 +365,18 @@ void BoardWidget::rightClicked() { m_editRotate += TileRotate::Deg45; validRotate(m_editRotate, tileInfo[index].rotates); + m_boardArea->setMouseMoveTileRotate(m_editRotate); } } + +void BoardWidget::actionSelected(const TileInfo* tileInfo) +{ + if(tileInfo) + { + validRotate(m_editRotate, tileInfo->rotates); + m_boardArea->setMouseMoveTileRotate(m_editRotate); + m_boardArea->setMouseMoveTileId(tileInfo->id); + } + else + m_boardArea->setMouseMoveTileId(TileId::None); +} diff --git a/client/src/board/boardwidget.hpp b/client/src/board/boardwidget.hpp index dd909689..21655abd 100644 --- a/client/src/board/boardwidget.hpp +++ b/client/src/board/boardwidget.hpp @@ -59,6 +59,8 @@ class BoardWidget : public QWidget QAction* m_editActionDelete; TileRotate m_editRotate; + void actionSelected(const TileInfo* tile); + protected slots: void worldEditChanged(bool value); void gridChanged(BoardAreaWidget::Grid value);