From a52104f627aeec0990ee46c8dca2bb975e4c0024 Mon Sep 17 00:00:00 2001 From: Reinder Feenstra Date: Thu, 30 Mar 2023 00:10:49 +0200 Subject: [PATCH] board: added block popupmenu with train actions --- client/src/board/boardwidget.cpp | 161 ++++++++++++++++--------------- client/src/board/tilemenu.cpp | 45 +++++++++ client/src/board/tilemenu.hpp | 39 ++++++++ 3 files changed, 165 insertions(+), 80 deletions(-) create mode 100644 client/src/board/tilemenu.cpp create mode 100644 client/src/board/tilemenu.hpp diff --git a/client/src/board/boardwidget.cpp b/client/src/board/boardwidget.cpp index 4f15c49b..a25c4cfb 100644 --- a/client/src/board/boardwidget.cpp +++ b/client/src/board/boardwidget.cpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2020-2022 Reinder Feenstra + * Copyright (C) 2020-2023 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -37,6 +37,7 @@ #include #include "getboardcolorscheme.hpp" #include "tilepainter.hpp" +#include "tilemenu.hpp" #include "../mainwindow.hpp" #include "../network/connection.hpp" #include "../network/property.hpp" @@ -540,97 +541,97 @@ void BoardWidget::tileClicked(int16_t x, int16_t y) } else { - auto it = m_object->tileData().find({x, y}); - if(it != m_object->tileData().end()) + if(ObjectPtr obj = m_object->getTileObject({x, y})) { - if(ObjectPtr obj = m_object->getTileObject({x, y})) + const auto tileId = m_object->getTileId({x, y}); + + if(tileId == TileId::PushButton) { - const auto tileId = it->second.id(); - - if(tileId == TileId::PushButton) + if(auto* m = obj->getMethod("pressed")) + m->call(); + } + else if(tileId == TileId::RailDecoupler) + { + if(const auto* state = obj->getProperty("state")) { - if(auto* m = obj->getMethod("pressed")) - m->call(); - } - else if(tileId == TileId::RailDecoupler) - { - if(const auto* state = obj->getProperty("state")) + switch(state->toEnum()) { - switch(state->toEnum()) - { - case DecouplerState::Deactivated: - obj->callMethod("activate"); - break; + case DecouplerState::Deactivated: + obj->callMethod("activate"); + break; - case DecouplerState::Activated: - obj->callMethod("deactivate"); - break; - } + case DecouplerState::Activated: + obj->callMethod("deactivate"); + break; } } - else + } + else if(tileId == TileId::RailBlock) + { + TileMenu::getBlockRailTileMenu(obj, this)->exec(QCursor::pos()); + } + else + { + AbstractProperty* value = nullptr; + Method* setValue = nullptr; + if(isRailTurnout(tileId)) { - AbstractProperty* value = nullptr; - Method* setValue = nullptr; - if(isRailTurnout(tileId)) - { - value = obj->getProperty("position"); - setValue = obj->getMethod("set_position"); - } - else if(isRailSignal(tileId)) - { - value = obj->getProperty("aspect"); - setValue = obj->getMethod("set_aspect"); - } - else if(tileId == TileId::RailDirectionControl) - { - value = obj->getProperty("state"); - setValue = obj->getMethod("set_state"); - } + value = obj->getProperty("position"); + setValue = obj->getMethod("set_position"); + } + else if(isRailSignal(tileId)) + { + value = obj->getProperty("aspect"); + setValue = obj->getMethod("set_aspect"); + } + else if(tileId == TileId::RailDirectionControl) + { + value = obj->getProperty("state"); + setValue = obj->getMethod("set_state"); + } - if(value && setValue) - { - const auto values = setValue->getAttribute(AttributeName::Values, QVariant()).toList(); + if(value && setValue) + { + const auto values = setValue->getAttribute(AttributeName::Values, QVariant()).toList(); - if(values.size() == 2) + if(values.size() == 2) + { + const auto n = (value->toInt() == values[0].toInt()) ? values[1].toInt() : values[0].toInt(); + callMethod(*setValue, nullptr, n); + } + else if(values.size() > 2) + { + auto tileRotate = TileRotate::Deg0; + if(auto* p = obj->getProperty("rotate")) + tileRotate = p->toEnum(); + + const int iconSize = 16; + QImage image(iconSize, iconSize, QImage::Format_ARGB32); + QPainter painter{&image}; + painter.setRenderHint(QPainter::Antialiasing, true); + TilePainter tilePainter{painter, iconSize, *getBoardColorScheme(BoardSettings::instance().colorScheme.value())}; + + QMenu menu(this); + for(const auto& v : values) { - const auto n = (value->toInt() == values[0].toInt()) ? values[1].toInt() : values[0].toInt(); - callMethod(*setValue, nullptr, n); - } - else if(values.size() > 2) - { - auto tileRotate = TileRotate::Deg0; - if(auto* p = obj->getProperty("rotate")) - tileRotate = p->toEnum(); - - const int iconSize = 16; - QImage image(iconSize, iconSize, QImage::Format_ARGB32); - QPainter painter{&image}; - painter.setRenderHint(QPainter::Antialiasing, true); - TilePainter tilePainter{painter, iconSize, *getBoardColorScheme(BoardSettings::instance().colorScheme.value())}; - - QMenu menu(this); - for(const auto& v : values) - { - const auto n = v.toInt(); - - image.fill(Qt::transparent); - - if(isRailTurnout(tileId)) - tilePainter.drawTurnout(tileId, image.rect(), tileRotate, static_cast(n)); - else if(isRailSignal(tileId)) - tilePainter.drawSignal(tileId, image.rect(), tileRotate, static_cast(n)); - else if(tileId == TileId::RailDirectionControl) - tilePainter.drawDirectionControl(tileId, image.rect(), tileRotate, static_cast(n)); - - connect(menu.addAction(QIcon(QPixmap::fromImage(image)), translateEnum(value->enumName(), n)), &QAction::triggered, - [this, setValue, n]() - { - callMethod(*setValue, nullptr, n); - }); - } - menu.exec(QCursor::pos()); + const auto n = v.toInt(); + + image.fill(Qt::transparent); + + if(isRailTurnout(tileId)) + tilePainter.drawTurnout(tileId, image.rect(), tileRotate, static_cast(n)); + else if(isRailSignal(tileId)) + tilePainter.drawSignal(tileId, image.rect(), tileRotate, static_cast(n)); + else if(tileId == TileId::RailDirectionControl) + tilePainter.drawDirectionControl(tileId, image.rect(), tileRotate, static_cast(n)); + + connect(menu.addAction(QIcon(QPixmap::fromImage(image)), translateEnum(value->enumName(), n)), &QAction::triggered, + [this, setValue, n]() + { + callMethod(*setValue, nullptr, n); + }); } + menu.exec(QCursor::pos()); } } } diff --git a/client/src/board/tilemenu.cpp b/client/src/board/tilemenu.cpp new file mode 100644 index 00000000..5d499e86 --- /dev/null +++ b/client/src/board/tilemenu.cpp @@ -0,0 +1,45 @@ +/** + * client/src/board/tilemenu.cpp + * + * This file is part of the traintastic source code. + * + * Copyright (C) 2023 Reinder Feenstra + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tilemenu.hpp" +#include +#include "../network/object.hpp" +#include "../dialog/objectselectlistdialog.hpp" +#include "../misc/methodaction.hpp" + +std::unique_ptr TileMenu::getBlockRailTileMenu(const ObjectPtr& tile, QWidget* parent) +{ + assert(tile->classId() == "board_tile.rail.block"); + + auto menu = std::make_unique(parent); + + if(auto* assignTrain = tile->getMethod("assign_train")) + menu->addAction(new MethodAction(*assignTrain, + [parent, assignTrain]() + { + std::make_unique(*assignTrain, parent)->exec(); + })); + if(auto* removeTrain = tile->getMethod("remove_train")) + menu->addAction(new MethodAction(*removeTrain)); + + return menu; +} diff --git a/client/src/board/tilemenu.hpp b/client/src/board/tilemenu.hpp new file mode 100644 index 00000000..bbc792d8 --- /dev/null +++ b/client/src/board/tilemenu.hpp @@ -0,0 +1,39 @@ +/** + * client/src/board/tilemenu.hpp + * + * This file is part of the traintastic source code. + * + * Copyright (C) 2023 Reinder Feenstra + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TRAINTASTIC_CLIENT_BOARD_TILEMENU_HPP +#define TRAINTASTIC_CLIENT_BOARD_TILEMENU_HPP + +#include +#include "../network/objectptr.hpp" + +class QWidget; +class QMenu; + +struct TileMenu +{ + TileMenu() = delete; + + static std::unique_ptr getBlockRailTileMenu(const ObjectPtr& tile, QWidget* parent = nullptr); +}; + +#endif