board: added switch tile

Dieser Commit ist enthalten in:
Reinder Feenstra 2024-05-05 18:28:43 +02:00
Ursprung 423cb9bb65
Commit 49ff1cb553
23 geänderte Dateien mit 441 neuen und 20 gelöschten Zeilen

Datei anzeigen

@ -170,6 +170,12 @@ void BoardAreaWidget::tileObjectAdded(int16_t x, int16_t y, const ObjectPtr& obj
}
break;
case TileId::Switch:
tryConnect("color_off");
tryConnect("color_on");
tryConnect("value");
break;
case TileId::None:
case TileId::RailStraight:
case TileId::RailCurve45:
@ -622,6 +628,20 @@ void BoardAreaWidget::paintEvent(QPaintEvent* event)
}
break;
}
case TileId::Switch:
if(auto sw = m_board.board().getTileObject(it.first)) /*[[likely]]*/
{
tilePainter.drawSwitch(r,
sw->getPropertyValueBool("value", false),
sw->getPropertyValueEnum<Color>("color_on", Color::Yellow),
sw->getPropertyValueEnum<Color>("color_off", Color::Gray));
}
else
{
tilePainter.drawSwitch(r);
}
break;
case TileId::None:
case TileId::ReservedForFutureExpension:
default:

Datei anzeigen

@ -409,7 +409,8 @@ BoardWidget::BoardWidget(std::shared_ptr<Board> object, QWidget* parent) :
isRailSignal(tileId) ||
tileId == TileId::RailDirectionControl ||
tileId == TileId::RailDecoupler ||
tileId == TileId::PushButton)
tileId == TileId::PushButton ||
tileId == TileId::Switch)
{
cursorShape = Qt::PointingHandCursor;
}
@ -597,6 +598,16 @@ void BoardWidget::tileClicked(int16_t x, int16_t y)
if(auto* m = obj->getMethod("pressed"))
m->call();
}
else if(tileId == TileId::Switch)
{
if(auto* value = obj->getProperty("value")) /*[[likely]]*/
{
if(auto* setValue = obj->getMethod("set_value")) /*[[likely]]*/
{
callMethod(*setValue, nullptr, !value->toBool());
}
}
}
else if(tileId == TileId::RailDecoupler)
{
if(const auto* state = obj->getProperty("state"))

Datei anzeigen

@ -172,6 +172,10 @@ void TilePainter::draw(TileId id, const QRectF& r, TileRotate rotate, bool isRes
drawLabel(r, rotate);
break;
case TileId::Switch:
drawSwitch(r);
break;
case TileId::None:
case TileId::ReservedForFutureExpension:
break;
@ -441,6 +445,15 @@ void TilePainter::drawPushButton(const QRectF& r, Color color)
m_painter.drawEllipse(r.center(), radius, radius);
}
void TilePainter::drawSwitch(const QRectF& r, bool value, Color colorOn, Color colorOff)
{
m_painter.setPen(QPen(Qt::gray, r.width() / 10));
m_painter.setBrush(toQColor(value ? colorOn : colorOff));
const qreal margin = r.width() * 0.1;
const qreal radius = r.width() * 0.15;
m_painter.drawRoundedRect(r.adjusted(margin, margin, -margin, -margin), radius, radius);
}
//=============================================================================
QColor TilePainter::sensorStateToColor(SensorState value) const

Datei anzeigen

@ -108,6 +108,7 @@ class TilePainter
void drawBlock(TileId id, const QRectF& r, TileRotate rotate, bool isReservedA = false, bool isReservedB = false, const ObjectPtr& blockTile = {});
void drawPushButton(const QRectF& r, Color color = Color::Yellow);
void drawSwitch(const QRectF& r, bool value = false, Color colorOn = Color::Yellow, Color colorOff = Color::Gray);
void drawRailDecoupler(const QRectF& r, TileRotate rotate, bool isReserved = false, DecouplerState active = DecouplerState::Deactivated);

Datei anzeigen

@ -133,7 +133,23 @@ void OutputMapWidget::updateItems(const std::vector<ObjectPtr>& items)
}
if(auto* p = items[i]->getProperty("key"))
m_table->setItem(i, columnKey, new QTableWidgetItem(translateEnum(*p)));
{
QString text;
if(p->type() == ValueType::Enum)
{
text = translateEnum(*p);
}
else if(p->type() == ValueType::Boolean)
{
text = p->toBool() ? "true" : "false";
}
else /*[[unlikely]]*/
{
assert(false);
text = "?";
}
m_table->setItem(i, columnKey, new QTableWidgetItem(text));
}
if(auto* outputActions = dynamic_cast<ObjectVectorProperty*>(items[i]->getVectorProperty("output_actions")))
{

Datei anzeigen

@ -107,6 +107,9 @@
"LABEL_TILE": {
"type": "constant"
},
"SWITCH_TILE": {
"type": "constant"
},
"LOCONET_INTERFACE": {
"type": "constant"
},
@ -196,4 +199,4 @@
"type": "constant",
"since": "0.3"
}
}
}

Datei anzeigen

@ -0,0 +1,24 @@
{
"name": {},
"color_on": {},
"color_off": {},
"value": {},
"toggle": {},
"set_value": {
"parameters": [
{
"name": "value"
}
]
},
"on_value_changed": {
"parameters": [
{
"name": "switch"
},
{
"name": "value"
}
]
}
}

Datei anzeigen

@ -1886,5 +1886,9 @@
{
"term": "object.labeltile:title",
"definition": "Label tile"
},
{
"term": "object.switchtile:title",
"definition": "Switch tile"
}
]
]

Datei anzeigen

@ -0,0 +1,97 @@
/**
* server/src/board/tile/misc/switchtile.cpp
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2024 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 "switchtile.hpp"
#include "../../../world/world.hpp"
#include "../../../core/objectproperty.tpp"
#include "../../../core/method.tpp"
#include "../../../core/attributes.hpp"
#include "../../../hardware/output/map/switchoutputmap.hpp"
#include "../../../utils/displayname.hpp"
CREATE_IMPL(SwitchTile)
SwitchTile::SwitchTile(World& world, std::string_view _id)
: Tile(world, _id, TileId::Switch)
, name{this, "name", id, PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::ScriptReadOnly}
, colorOn{this, "color_on", Color::Yellow, PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::ScriptReadOnly}
, colorOff{this, "color_off", Color::Gray, PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::ScriptReadOnly}
, value{this, "value", false, PropertyFlags::ReadOnly | PropertyFlags::Store | PropertyFlags::ScriptReadOnly}
, outputMap{this, "output_map", nullptr, PropertyFlags::ReadOnly | PropertyFlags::Store | PropertyFlags::SubObject | PropertyFlags::NoScript}
, toggle{*this, "toggle", MethodFlags::ScriptCallable,
[this]()
{
value = !value;
}}
, setValue(*this, "set_value", MethodFlags::ScriptCallable,
[this](bool newValue)
{
if(value != newValue)
{
(*outputMap)[newValue]->execute();
value.setValueInternal(newValue);
fireEvent(onValueChanged, shared_ptr<SwitchTile>(), newValue);
}
})
, onValueChanged{*this, "on_value_changed", EventFlags::Scriptable}
{
outputMap.setValueInternal(std::make_shared<SwitchOutputMap>(*this, outputMap.name()));
const bool editable = contains(m_world.state.value(), WorldState::Edit);
Attributes::addDisplayName(name, DisplayName::Object::name);
Attributes::addEnabled(name, editable);
m_interfaceItems.add(name);
Attributes::addEnabled(colorOn, editable);
Attributes::addValues(colorOn, colorValuesWithoutNone);
m_interfaceItems.add(colorOn);
Attributes::addEnabled(colorOff, editable);
Attributes::addValues(colorOff, colorValuesWithoutNone);
m_interfaceItems.add(colorOff);
Attributes::addObjectEditor(value, false);
m_interfaceItems.add(value);
Attributes::addDisplayName(outputMap, DisplayName::BoardTile::outputMap);
m_interfaceItems.add(outputMap);
Attributes::addObjectEditor(toggle, false);
m_interfaceItems.add(toggle);
Attributes::addObjectEditor(setValue, false);
m_interfaceItems.add(setValue);
m_interfaceItems.add(onValueChanged);
}
void SwitchTile::worldEvent(WorldState worldState, WorldEvent worldEvent)
{
Tile::worldEvent(worldState, worldEvent);
const bool editable = contains(worldState, WorldState::Edit);
Attributes::setEnabled(name, editable);
Attributes::setEnabled(colorOn, editable);
Attributes::setEnabled(colorOff, editable);
}

Datei anzeigen

@ -0,0 +1,56 @@
/**
* server/src/board/tile/misc/switchtile.hpp
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2024 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_SERVER_BOARD_TILE_MISC_SWITCHTILE_HPP
#define TRAINTASTIC_SERVER_BOARD_TILE_MISC_SWITCHTILE_HPP
#include "../tile.hpp"
#include "../../../core/objectproperty.hpp"
#include "../../../core/method.hpp"
#include "../../../core/event.hpp"
#include "../../../enum/color.hpp"
class SwitchOutputMap;
class SwitchTile : public Tile
{
CLASS_ID("board_tile.misc.switch")
DEFAULT_ID("switch")
CREATE_DEF(SwitchTile)
protected:
void worldEvent(WorldState worldState, WorldEvent worldEvent) final;
public:
Property<std::string> name;
Property<Color> colorOn;
Property<Color> colorOff;
Property<bool> value;
ObjectProperty<SwitchOutputMap> outputMap;
Method<void()> toggle;
Method<void(bool)> setValue;
Event<std::shared_ptr<SwitchTile>, bool> onValueChanged;
SwitchTile(World& world, std::string_view _id);
};
#endif

Datei anzeigen

@ -25,6 +25,7 @@
#include "rail/linkrailtile.hpp"
#include "rail/nxbuttonrailtile.hpp"
#include "misc/labeltile.hpp"
#include "misc/switchtile.hpp"
#include "../../utils/ifclassidcreate.hpp"
#include "../../world/world.hpp"
@ -61,6 +62,7 @@ std::shared_ptr<Tile> Tiles::create(World& world, std::string_view classId, std:
IF_CLASSID_CREATE(DecouplerRailTile)
IF_CLASSID_CREATE(NXButtonRailTile)
IF_CLASSID_CREATE(LabelTile)
IF_CLASSID_CREATE(SwitchTile)
return std::shared_ptr<Tile>();
}
@ -119,6 +121,7 @@ const std::vector<Tiles::Info>& Tiles::getInfo()
Info{PushButtonTile::classId, TileId::PushButton, rotateNone, {miscellaneous}},
Info{LabelTile::classId, TileId::Label, rotateFull90, {miscellaneous}},
Info{SwitchTile::classId, TileId::Switch, rotateNone, {miscellaneous}},
}};
return info;

Datei anzeigen

@ -302,6 +302,7 @@ OutputMap::OutputMap(Object& _parent, std::string_view parentPropertyName)
m_interfaceItems.add(addresses);
Attributes::addAliases(ecosObject, tcb::span<const uint16_t>{}, tcb::span<const std::string>{});
Attributes::addDisplayName(ecosObject, "output_map:ecos_object");
Attributes::addEnabled(ecosObject, editable);
Attributes::addValues(ecosObject, tcb::span<const uint16_t>{});
Attributes::addVisible(ecosObject, false);
@ -309,10 +310,12 @@ OutputMap::OutputMap(Object& _parent, std::string_view parentPropertyName)
m_interfaceItems.add(items);
Attributes::addDisplayName(addAddress, "output_map:add_address");
Attributes::addEnabled(addAddress, false);
Attributes::addVisible(addAddress, false);
m_interfaceItems.add(addAddress);
Attributes::addDisplayName(removeAddress, "output_map:remove_address");
Attributes::addEnabled(removeAddress, false);
Attributes::addVisible(removeAddress, false);
m_interfaceItems.add(removeAddress);

Datei anzeigen

@ -66,7 +66,18 @@ class OutputMapItemBase : public OutputMapItem
{
std::string id{m_map.getObjectId()};
id.append(".");
id.append(EnumValues<Key>::value.find(key)->second);
if constexpr(std::is_enum_v<Key>)
{
id.append(EnumValues<Key>::value.find(key)->second);
}
else if constexpr(std::is_same_v<Key, bool>)
{
id.append(key ? "true" : "false");
}
else
{
static_assert(sizeof(Key) != sizeof(Key));
}
return id;
}
};

Datei anzeigen

@ -0,0 +1,37 @@
/**
* server/src/hardware/output/map/switchoutputmap.cpp
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2024 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 "switchoutputmap.hpp"
static std::optional<OutputActionValue> getDefaultActionValue(bool value, OutputType outputType, size_t outputIndex)
{
// FIXME: implement defaults
(void)value;
(void)outputType;
(void)outputIndex;
return {};
}
SwitchOutputMap::SwitchOutputMap(Object& _parent, std::string_view parentPropertyName) :
OutputMapBase(_parent, parentPropertyName, {false, true}, getDefaultActionValue)
{
}

Datei anzeigen

@ -0,0 +1,37 @@
/**
* server/src/hardware/output/map/switchoutputmap.hpp
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2024 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_SERVER_HARDWARE_OUTPUT_MAP_SWITCHOUTPUTMAP_HPP
#define TRAINTASTIC_SERVER_HARDWARE_OUTPUT_MAP_SWITCHOUTPUTMAP_HPP
#include "outputmapbase.hpp"
#include "switchoutputmapitem.hpp"
class SwitchOutputMap : public OutputMapBase<bool, SwitchOutputMapItem>
{
CLASS_ID("output_map.switch")
public:
SwitchOutputMap(Object& _parent, std::string_view parentPropertyName);
};
#endif

Datei anzeigen

@ -0,0 +1,29 @@
/**
* server/src/hardware/output/map/switchoutputmapitem.cpp
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2024 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 "switchoutputmapitem.hpp"
#include "../../../core/method.tpp"
SwitchOutputMapItem::SwitchOutputMapItem(Object& map, bool value) :
OutputMapItemBase(map, value)
{
}

Datei anzeigen

@ -0,0 +1,36 @@
/**
* server/src/hardware/output/map/switchoutputmapitem.hpp
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2024 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_SERVER_HARDWARE_OUTPUT_MAP_SWITCHOUTPUTMAPITEM_HPP
#define TRAINTASTIC_SERVER_HARDWARE_OUTPUT_MAP_SWITCHOUTPUTMAPITEM_HPP
#include "outputmapitembase.hpp"
class SwitchOutputMapItem : public OutputMapItemBase<bool>
{
CLASS_ID("output_map_item.switch")
public:
SwitchOutputMapItem(Object& map, bool value);
};
#endif

Datei anzeigen

@ -31,6 +31,7 @@
#include "../board/tile/misc/labeltile.hpp"
#include "../board/tile/misc/pushbuttontile.hpp"
#include "../board/tile/misc/switchtile.hpp"
#include "../board/tile/rail/nxbuttonrailtile.hpp"
#include "../board/tile/rail/sensorrailtile.hpp"
#include "../board/tile/rail/straightrailtile.hpp"
@ -153,6 +154,7 @@ void Class::registerValues(lua_State* L)
registerValue<LabelTile>(L, "LABEL_TILE");
registerValue<PushButtonTile>(L, "PUSH_BUTTON_TILE");
registerValue<SwitchTile>(L, "SWITCH_TILE");
registerValue<NXButtonRailTile>(L, "NX_BUTTON_RAIL_TILE");
registerValue<StraightRailTile>(L, "STRAIGHT_RAIL_TILE");
registerValue<TunnelRailTile>(L, "TUNNEL_RAIL_TILE");

Datei anzeigen

@ -59,6 +59,7 @@ enum class TileId : uint16_t // 10 bit
RailDecoupler = 29,
RailNXButton = 30,
Label = 31,
Switch = 32,
ReservedForFutureExpension = 1023
};
@ -193,6 +194,7 @@ constexpr bool isActive(TileId id)
case TileId::RailDecoupler:
case TileId::RailNXButton:
case TileId::Label:
case TileId::Switch:
return true;
default:

Datei anzeigen

@ -5373,7 +5373,7 @@
"fuzzy": 0
},
{
"term": "output_map.signal:add_address",
"term": "output_map:add_address",
"definition": "Adresse hinzuf\u00fcgen",
"context": "",
"term_plural": "",
@ -5382,7 +5382,7 @@
"fuzzy": 0
},
{
"term": "output_map.signal:remove_address",
"term": "output_map:remove_address",
"definition": "Adresse entfernen",
"context": "",
"term_plural": "",
@ -5391,7 +5391,7 @@
"fuzzy": 0
},
{
"term": "output_map.signal:ecos_object",
"term": "output_map:ecos_object",
"definition": "ECoS-Objekt",
"context": "",
"term_plural": "",
@ -6155,4 +6155,4 @@
"comment": "",
"fuzzy": 0
}
]
]

Datei anzeigen

@ -4464,15 +4464,15 @@
"definition": "ECoS object"
},
{
"term": "output_map.signal:add_address",
"term": "output_map:add_address",
"definition": "Add address"
},
{
"term": "output_map.signal:remove_address",
"term": "output_map:remove_address",
"definition": "Remove address"
},
{
"term": "output_map.signal:ecos_object",
"term": "output_map:ecos_object",
"definition": "ECoS object"
},
{
@ -4810,5 +4810,21 @@
{
"term": "wizard.new_board.finalization:text",
"definition": "Lets go build the board!"
},
{
"term": "class_id:board_tile.misc.switch",
"definition": "Switch"
},
{
"term": "board_tile.misc.switch:color_on",
"definition": "Color when on"
},
{
"term": "board_tile.misc.switch:color_off",
"definition": "Color when off"
},
{
"term": "output_map.switch:key",
"definition": "Value"
}
]
]

Datei anzeigen

@ -4464,15 +4464,15 @@
"definition": "ECoS object"
},
{
"term": "output_map.signal:add_address",
"term": "output_map:add_address",
"definition": "Aggiungi indirizzo"
},
{
"term": "output_map.signal:remove_address",
"term": "output_map:remove_address",
"definition": "Rimuovi indirizzo"
},
{
"term": "output_map.signal:ecos_object",
"term": "output_map:ecos_object",
"definition": "ECoS object"
},
{

Datei anzeigen

@ -5373,7 +5373,7 @@
"fuzzy": 0
},
{
"term": "output_map.signal:add_address",
"term": "output_map:add_address",
"definition": "Adres toevoegen",
"context": "",
"term_plural": "",
@ -5382,7 +5382,7 @@
"fuzzy": 0
},
{
"term": "output_map.signal:remove_address",
"term": "output_map:remove_address",
"definition": "Adres verwijderen",
"context": "",
"term_plural": "",
@ -5391,7 +5391,7 @@
"fuzzy": 0
},
{
"term": "output_map.signal:ecos_object",
"term": "output_map:ecos_object",
"definition": "ECoS object",
"context": "",
"term_plural": "",
@ -6155,4 +6155,4 @@
"comment": "",
"fuzzy": 0
}
]
]