diff --git a/config/schemas/template.json b/config/schemas/template.json index c2daebbad..d139f257b 100644 --- a/config/schemas/template.json +++ b/config/schemas/template.json @@ -44,9 +44,9 @@ "treasureLikeZone" : { "type" : "number" }, "customObjectsLikeZone" : { "type" : "number" }, - "visPositionX" : { "type" : "number" }, - "visPositionY" : { "type" : "number" }, - "visSize" : { "type" : "number" }, + "visiblePositionX" : { "type" : "number" }, + "visiblePositionY" : { "type" : "number" }, + "visibleSize" : { "type" : "number" }, "terrainTypes": {"$ref" : "#/definitions/stringArray"}, "bannedTerrains": {"$ref" : "#/definitions/stringArray"}, diff --git a/lib/rmg/CRmgTemplate.cpp b/lib/rmg/CRmgTemplate.cpp index 1744bc056..749f16e6c 100644 --- a/lib/rmg/CRmgTemplate.cpp +++ b/lib/rmg/CRmgTemplate.cpp @@ -153,8 +153,8 @@ ZoneOptions::ZoneOptions(): terrainTypeLikeZone(NO_ZONE), treasureLikeZone(NO_ZONE), customObjectsLikeZone(NO_ZONE), - visPosition(Point(0, 0)), - visSize(1.0) + visiblePosition(Point(0, 0)), + visibleSize(1.0) { } @@ -334,24 +334,24 @@ TRmgTemplateZoneId ZoneOptions::getTownsLikeZone() const return townsLikeZone; } -Point ZoneOptions::getVisPosition() const +Point ZoneOptions::getVisiblePosition() const { - return visPosition; + return visiblePosition; } -void ZoneOptions::setVisPosition(Point value) +void ZoneOptions::setVisiblePosition(Point value) { - visPosition = value; + visiblePosition = value; } -float ZoneOptions::getVisSize() const +float ZoneOptions::getVisibleSize() const { - return visSize; + return visibleSize; } -void ZoneOptions::setVisSize(float value) +void ZoneOptions::setVisibleSize(float value) { - visSize = value; + visibleSize = value; } void ZoneOptions::addConnection(const ZoneConnection & connection) @@ -519,9 +519,9 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler) } handler.serializeStruct("customObjects", objectConfig); - handler.serializeInt("visPositionX", visPosition.x); - handler.serializeInt("visPositionY", visPosition.y); - handler.serializeFloat("visSize", visSize); + handler.serializeInt("visiblePositionX", visiblePosition.x); + handler.serializeInt("visiblePositionY", visiblePosition.y); + handler.serializeFloat("visibleSize", visibleSize); } ZoneConnection::ZoneConnection(): diff --git a/lib/rmg/CRmgTemplate.h b/lib/rmg/CRmgTemplate.h index 8ad751c9c..fc9fb8ac0 100644 --- a/lib/rmg/CRmgTemplate.h +++ b/lib/rmg/CRmgTemplate.h @@ -241,11 +241,11 @@ public: TRmgTemplateZoneId getCustomObjectsLikeZone() const; TRmgTemplateZoneId getTownsLikeZone() const; - Point getVisPosition() const; - void setVisPosition(Point value); + Point getVisiblePosition() const; + void setVisiblePosition(Point value); - float getVisSize() const; - void setVisSize(float value); + float getVisibleSize() const; + void setVisibleSize(float value); protected: TRmgTemplateZoneId id; @@ -254,8 +254,8 @@ protected: ui32 maxTreasureValue; std::optional owner; - Point visPosition; - float visSize; + Point visiblePosition; + float visibleSize; ObjectConfig objectConfig; CTownInfo playerTowns; diff --git a/mapeditor/CMakeLists.txt b/mapeditor/CMakeLists.txt index bbf9c7ffa..05254894a 100644 --- a/mapeditor/CMakeLists.txt +++ b/mapeditor/CMakeLists.txt @@ -54,8 +54,9 @@ if(ENABLE_TEMPLATE_EDITOR) ${editor_SRCS} templateeditor/templateeditor.cpp templateeditor/templateview.cpp - templateeditor/graphicelements.cpp - templateeditor/algorithm.cpp + templateeditor/graphicelements/CardItem.cpp + templateeditor/graphicelements/LineItem.cpp + templateeditor/GeometryAlgorithm.cpp templateeditor/terrainselector.cpp templateeditor/factionselector.cpp templateeditor/mineselector.cpp @@ -119,8 +120,9 @@ if(ENABLE_TEMPLATE_EDITOR) ${editor_HEADERS} templateeditor/templateeditor.h templateeditor/templateview.h - templateeditor/graphicelements.h - templateeditor/algorithm.h + templateeditor/graphicelements/CardItem.h + templateeditor/graphicelements/LineItem.h + templateeditor/GeometryAlgorithm.h templateeditor/terrainselector.h templateeditor/factionselector.h templateeditor/mineselector.h diff --git a/mapeditor/templateeditor/algorithm.cpp b/mapeditor/templateeditor/GeometryAlgorithm.cpp similarity index 90% rename from mapeditor/templateeditor/algorithm.cpp rename to mapeditor/templateeditor/GeometryAlgorithm.cpp index 4f73e1895..9a8f25c43 100644 --- a/mapeditor/templateeditor/algorithm.cpp +++ b/mapeditor/templateeditor/GeometryAlgorithm.cpp @@ -1,5 +1,5 @@ /* - * algorithm.cpp, part of VCMI engine + * GeometryAlgorithm.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -9,14 +9,14 @@ */ #include "StdInc.h" -#include "algorithm.h" +#include "GeometryAlgorithm.h" -double Algorithm::distance(double x1, double y1, double x2, double y2) +double GeometryAlgorithm::distance(double x1, double y1, double x2, double y2) { return std::sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)) + 1e-9; } -bool Algorithm::edgesIntersect(const Node& a, const Node& b, const Node& c, const Node& d) +bool GeometryAlgorithm::edgesIntersect(const Node& a, const Node& b, const Node& c, const Node& d) { auto cross = [](double x1, double y1, double x2, double y2) { return x1 * y2 - y1 * x2; @@ -35,7 +35,7 @@ bool Algorithm::edgesIntersect(const Node& a, const Node& b, const Node& c, cons return s > 0 && s < 1 && t > 0 && t < 1; } -void Algorithm::forceDirectedLayout(std::vector & nodes, const std::vector & edges, int iterations, double width, double height) +void GeometryAlgorithm::forceDirectedLayout(std::vector & nodes, const std::vector & edges, int iterations, double width, double height) { const double area = width * height; const double k = std::sqrt(area / nodes.size()); diff --git a/mapeditor/templateeditor/algorithm.h b/mapeditor/templateeditor/GeometryAlgorithm.h similarity index 91% rename from mapeditor/templateeditor/algorithm.h rename to mapeditor/templateeditor/GeometryAlgorithm.h index aed4131ca..8de556be4 100644 --- a/mapeditor/templateeditor/algorithm.h +++ b/mapeditor/templateeditor/GeometryAlgorithm.h @@ -1,5 +1,5 @@ /* - * algorithm.h, part of VCMI engine + * GeometryAlgorithm.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -11,7 +11,7 @@ #include "../StdInc.h" -class Algorithm +class GeometryAlgorithm { public: struct Node diff --git a/mapeditor/templateeditor/graphicelements.cpp b/mapeditor/templateeditor/graphicelements/CardItem.cpp similarity index 82% rename from mapeditor/templateeditor/graphicelements.cpp rename to mapeditor/templateeditor/graphicelements/CardItem.cpp index 547872f67..cf6359802 100644 --- a/mapeditor/templateeditor/graphicelements.cpp +++ b/mapeditor/templateeditor/graphicelements/CardItem.cpp @@ -1,5 +1,5 @@ /* - * graphicelements.cpp, part of VCMI engine + * CardItem.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -9,12 +9,12 @@ */ #include "StdInc.h" -#include "graphicelements.h" +#include "CardItem.h" #include -#include "../../lib/constants/EntityIdentifiers.h" -#include "../../lib/rmg/CRmgTemplate.h" +#include "../../../lib/constants/EntityIdentifiers.h" +#include "../../../lib/rmg/CRmgTemplate.h" QDomElement CardItem::getElementById(const QDomDocument& doc, const QString& id) { @@ -176,7 +176,7 @@ void CardItem::setChestValue(int val) iconElem.setAttribute("opacity", val ? "1.0" : "0.1"); } -void CardItem::setSword(EMonsterStrength::EMonsterStrength val) +void CardItem::setMonsterStrength(EMonsterStrength::EMonsterStrength val) { int level = 0; if(val == EMonsterStrength::ZONE_WEAK || val == EMonsterStrength::GLOBAL_WEAK) @@ -227,66 +227,3 @@ QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value) return QGraphicsSvgItem::itemChange(change, value); } - -LineItem::LineItem(): - clickCallback(nullptr) -{ - setZValue(-2); - for(int i = 0; i < 10; i++) // render multiple times to increase outline effect - { - auto tmpTextItem = new QGraphicsTextItem(this); - tmpTextItem->setZValue(-1); - QFont font; - font.setPointSize(18); - tmpTextItem->setFont(font); - QGraphicsDropShadowEffect *shadowEffect = new QGraphicsDropShadowEffect(); - shadowEffect->setBlurRadius(10); - shadowEffect->setEnabled(true); - shadowEffect->setOffset(0, 0); - shadowEffect->setColor(Qt::black); - tmpTextItem->setGraphicsEffect(shadowEffect); - tmpTextItem->setDefaultTextColor(Qt::white); - textItem.push_back(tmpTextItem); - } -} - -void LineItem::setLineToolTip(const QString &toolTip) -{ - for(auto & tmpTextItem : textItem) - tmpTextItem->setToolTip(toolTip); - setToolTip(toolTip); -} - -void LineItem::setClickCallback(std::function func) -{ - clickCallback = func; -} - -void LineItem::setText(QString text) -{ - for(auto & tmpTextItem : textItem) - { - tmpTextItem->setPlainText(text); - QRectF lineRect = boundingRect(); - QRectF textRect = tmpTextItem->boundingRect(); - tmpTextItem->setPos(QPointF(lineRect.x() + (lineRect.width() / 2) - (textRect.width() / 2), lineRect.y() + (lineRect.height() / 2) - (textRect.height() / 2))); - } -} - -void LineItem::setId(int val) -{ - id = val; -} - -int LineItem::getId() -{ - return id; -} - -void LineItem::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if(event->button() == Qt::LeftButton && clickCallback) - clickCallback(); - - QGraphicsLineItem::mousePressEvent(event); -} \ No newline at end of file diff --git a/mapeditor/templateeditor/graphicelements.h b/mapeditor/templateeditor/graphicelements/CardItem.h similarity index 64% rename from mapeditor/templateeditor/graphicelements.h rename to mapeditor/templateeditor/graphicelements/CardItem.h index 465992e60..1dc3d3d1b 100644 --- a/mapeditor/templateeditor/graphicelements.h +++ b/mapeditor/templateeditor/graphicelements/CardItem.h @@ -1,5 +1,5 @@ /* - * graphicelements.h, part of VCMI engine + * CardItem.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -11,9 +11,9 @@ #include #include -#include "../StdInc.h" -#include "../../lib/constants/EntityIdentifiers.h" -#include "../../lib/rmg/CRmgTemplate.h" +#include "../../StdInc.h" +#include "../../../lib/constants/EntityIdentifiers.h" +#include "../../../lib/rmg/CRmgTemplate.h" class CardItem : public QGraphicsSvgItem { @@ -44,30 +44,10 @@ public: int getId(); void setResAmount(GameResID res, int val); void setChestValue(int val); - void setSword(EMonsterStrength::EMonsterStrength val); + void setMonsterStrength(EMonsterStrength::EMonsterStrength val); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; }; - -class LineItem : public QGraphicsLineItem -{ -private: - std::vector textItem; - std::function clickCallback; - int id = -1; - - static constexpr int CLICKABLE_PADDING_AROUND_LINE = 10; -public: - LineItem(); - void setClickCallback(std::function func); - void setText(QString text); - void setId(int val); - int getId(); - void setLineToolTip(const QString &toolTip); - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *event) override; -}; diff --git a/mapeditor/templateeditor/graphicelements/LineItem.cpp b/mapeditor/templateeditor/graphicelements/LineItem.cpp new file mode 100644 index 000000000..9f7b78609 --- /dev/null +++ b/mapeditor/templateeditor/graphicelements/LineItem.cpp @@ -0,0 +1,77 @@ +/* + * LineItem.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#include "StdInc.h" + +#include "LineItem.h" + +#include + +LineItem::LineItem(): + clickCallback(nullptr) +{ + setZValue(-2); + for(int i = 0; i < 10; i++) // render multiple times to increase outline effect + { + auto tmpTextItem = new QGraphicsTextItem(this); + tmpTextItem->setZValue(-1); + QFont font; + font.setPointSize(18); + tmpTextItem->setFont(font); + QGraphicsDropShadowEffect *shadowEffect = new QGraphicsDropShadowEffect(); + shadowEffect->setBlurRadius(10); + shadowEffect->setEnabled(true); + shadowEffect->setOffset(0, 0); + shadowEffect->setColor(Qt::black); + tmpTextItem->setGraphicsEffect(shadowEffect); + tmpTextItem->setDefaultTextColor(Qt::white); + textItem.push_back(tmpTextItem); + } +} + +void LineItem::setLineToolTip(const QString &toolTip) +{ + for(auto & tmpTextItem : textItem) + tmpTextItem->setToolTip(toolTip); + setToolTip(toolTip); +} + +void LineItem::setClickCallback(std::function func) +{ + clickCallback = func; +} + +void LineItem::setText(QString text) +{ + for(auto & tmpTextItem : textItem) + { + tmpTextItem->setPlainText(text); + QRectF lineRect = boundingRect(); + QRectF textRect = tmpTextItem->boundingRect(); + tmpTextItem->setPos(QPointF(lineRect.x() + (lineRect.width() / 2) - (textRect.width() / 2), lineRect.y() + (lineRect.height() / 2) - (textRect.height() / 2))); + } +} + +void LineItem::setId(int val) +{ + id = val; +} + +int LineItem::getId() +{ + return id; +} + +void LineItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if(event->button() == Qt::LeftButton && clickCallback) + clickCallback(); + + QGraphicsLineItem::mousePressEvent(event); +} diff --git a/mapeditor/templateeditor/graphicelements/LineItem.h b/mapeditor/templateeditor/graphicelements/LineItem.h new file mode 100644 index 000000000..831b08b38 --- /dev/null +++ b/mapeditor/templateeditor/graphicelements/LineItem.h @@ -0,0 +1,34 @@ +/* + * LineItem.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once +#include +#include + +#include "../../StdInc.h" + +class LineItem : public QGraphicsLineItem +{ +private: + std::vector textItem; + std::function clickCallback; + int id = -1; + + static constexpr int CLICKABLE_PADDING_AROUND_LINE = 10; +public: + LineItem(); + void setClickCallback(std::function func); + void setText(QString text); + void setId(int val); + int getId(); + void setLineToolTip(const QString &toolTip); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event) override; +}; diff --git a/mapeditor/templateeditor/templateeditor.cpp b/mapeditor/templateeditor/templateeditor.cpp index 6158b7a84..f716f8b6b 100644 --- a/mapeditor/templateeditor/templateeditor.cpp +++ b/mapeditor/templateeditor/templateeditor.cpp @@ -10,11 +10,12 @@ #include "StdInc.h" #include "templateeditor.h" #include "ui_templateeditor.h" -#include "graphicelements.h" +#include "graphicelements/CardItem.h" +#include "graphicelements/LineItem.h" #include "terrainselector.h" #include "factionselector.h" #include "mineselector.h" -#include "algorithm.h" +#include "GeometryAlgorithm.h" #include "../helper.h" @@ -88,29 +89,29 @@ void TemplateEditor::autoPositionZones() { auto & zones = templates[selectedTemplate]->getZones(); - std::vector nodes; + std::vector nodes; std::default_random_engine rng(0); std::uniform_real_distribution distX(0.0, 500); std::uniform_real_distribution distY(0.0, 500); for(auto & item : zones) { - Algorithm::Node node; + GeometryAlgorithm::Node node; node.x = distX(rng); node.y = distY(rng); node.id = item.first; nodes.push_back(node); } - std::vector edges; + std::vector edges; for(auto & item : templates[selectedTemplate]->getConnectedZoneIds()) edges.push_back({ vstd::find_pos_if(nodes, [item](auto & elem){ return elem.id == item.getZoneA(); }), vstd::find_pos_if(nodes, [item](auto & elem){ return elem.id == item.getZoneB(); }) }); - Algorithm::forceDirectedLayout(nodes, edges, 1000, 500, 500); + GeometryAlgorithm::forceDirectedLayout(nodes, edges, 1000, 500, 500); for(auto & item : nodes) - zones.at(item.id)->setVisPosition(Point(CardItem::GRID_SIZE * round(item.x / CardItem::GRID_SIZE), CardItem::GRID_SIZE * round(item.y / CardItem::GRID_SIZE))); + zones.at(item.id)->setVisiblePosition(Point(CardItem::GRID_SIZE * round(item.x / CardItem::GRID_SIZE), CardItem::GRID_SIZE * round(item.y / CardItem::GRID_SIZE))); } void TemplateEditor::loadContent(bool autoPosition) @@ -126,12 +127,12 @@ void TemplateEditor::loadContent(bool autoPosition) return; auto & zones = templates[selectedTemplate]->getZones(); - if(autoPosition || std::all_of(zones.begin(), zones.end(), [](auto & item){ return item.second->getVisPosition().x == 0 && item.second->getVisPosition().y == 0; })) + if(autoPosition || std::all_of(zones.begin(), zones.end(), [](auto & item){ return item.second->getVisiblePosition().x == 0 && item.second->getVisiblePosition().y == 0; })) autoPositionZones(); for(auto & zone : zones) - if(zone.second->getVisSize() < 0.01) - zone.second->setVisSize(1.0); + if(zone.second->getVisibleSize() < 0.01) + zone.second->setVisibleSize(1.0); for(auto & zone : zones) { @@ -153,8 +154,8 @@ void TemplateEditor::loadContent(bool autoPosition) for(auto & zone : templates[selectedTemplate]->getZones()) if(zone.first == svgItem->getId()) { - zone.second->setVisPosition(Point(svgItem->pos().toPoint().rx() + (svgItem->boundingRect().width() * svgItem->scale() / 2), svgItem->pos().toPoint().ry() + (svgItem->boundingRect().height() * svgItem->scale() / 2))); - zone.second->setVisSize(svgItem->scale()); + zone.second->setVisiblePosition(Point(svgItem->pos().toPoint().rx() + (svgItem->boundingRect().width() * svgItem->scale() / 2), svgItem->pos().toPoint().ry() + (svgItem->boundingRect().height() * svgItem->scale() / 2))); + zone.second->setVisibleSize(svgItem->scale()); } loadZoneMenuContent(true); }); @@ -241,8 +242,8 @@ void TemplateEditor::updateZonePositions() for(auto & card : cards) { auto & zone = templates[selectedTemplate]->getZones().at(card.first); - card.second->setPos(zone->getVisPosition().x - (card.second->boundingRect().width() * card.second->scale() / 2), zone->getVisPosition().y - (card.second->boundingRect().height() * card.second->scale() / 2)); - card.second->setScale(zone->getVisSize()); + card.second->setPos(zone->getVisiblePosition().x - (card.second->boundingRect().width() * card.second->scale() / 2), zone->getVisiblePosition().y - (card.second->boundingRect().height() * card.second->scale() / 2)); + card.second->setScale(zone->getVisibleSize()); } updateConnectionLines(); @@ -282,9 +283,9 @@ void TemplateEditor::updateZoneCards(TRmgTemplateZoneId id) for(auto & res : {GameResID::WOOD, GameResID::ORE, GameResID::MERCURY, GameResID::SULFUR, GameResID::CRYSTAL, GameResID::GEMS, GameResID::GOLD}) card.second->setResAmount(res, zone->getMinesInfo().count(res) ? zone->getMinesInfo().at(res) : 0); card.second->setChestValue(zone->getMaxTreasureValue()); - card.second->setSword(zone->monsterStrength); + card.second->setMonsterStrength(zone->monsterStrength); card.second->setToolTip(getZoneToolTip(zone)); - card.second->setScale(zone->getVisSize()); + card.second->setScale(zone->getVisibleSize()); card.second->updateContent(); } } @@ -296,9 +297,9 @@ void TemplateEditor::loadZoneMenuContent(bool onlyPosition) auto setValue = [](auto& target, const auto& newValue){ target->setValue(newValue); }; auto & zone = templates[selectedTemplate]->getZones().at(selectedZone); - setValue(ui->spinBoxZoneVisPosX, zone->getVisPosition().x); - setValue(ui->spinBoxZoneVisPosY, zone->getVisPosition().y); - setValue(ui->doubleSpinBoxZoneVisSize, zone->getVisSize()); + setValue(ui->spinBoxZoneVisPosX, zone->getVisiblePosition().x); + setValue(ui->spinBoxZoneVisPosY, zone->getVisiblePosition().y); + setValue(ui->doubleSpinBoxZoneVisSize, zone->getVisibleSize()); if(onlyPosition) return; @@ -467,8 +468,8 @@ void TemplateEditor::saveZoneMenuContent() auto zone = templates[selectedTemplate]->getZones().at(selectedZone); auto type = static_cast(ui->comboBoxZoneType->currentData().toInt()); - zone->setVisPosition(Point(ui->spinBoxZoneVisPosX->value(), ui->spinBoxZoneVisPosY->value())); - zone->setVisSize(ui->doubleSpinBoxZoneVisSize->value()); + zone->setVisiblePosition(Point(ui->spinBoxZoneVisPosX->value(), ui->spinBoxZoneVisPosY->value())); + zone->setVisibleSize(ui->doubleSpinBoxZoneVisSize->value()); zone->setType(type); zone->setSize(ui->spinBoxZoneSize->value()); zone->playerTowns.townCount = ui->spinBoxTownCountPlayer->value();