diff --git a/plugins/robots/common/twoDModel/include/twoDModel/engine/model/metricCoordinateSystem.h b/plugins/robots/common/twoDModel/include/twoDModel/engine/model/metricCoordinateSystem.h index 3782836170..3ece58158c 100644 --- a/plugins/robots/common/twoDModel/include/twoDModel/engine/model/metricCoordinateSystem.h +++ b/plugins/robots/common/twoDModel/include/twoDModel/engine/model/metricCoordinateSystem.h @@ -29,10 +29,10 @@ class MetricCoordinateSystem: public graphicsUtils::AbstractCoordinateSystem { Q_OBJECT public: - explicit MetricCoordinateSystem(twoDModel::model::SizeUnit *metricSystem, + explicit MetricCoordinateSystem(const QSharedPointer &metricSystem, QObject* parent = nullptr); - ~MetricCoordinateSystem(); + ~MetricCoordinateSystem() override; /// Conversе of units of measurement into pixels qreal toPx(const qreal size) const override; @@ -46,9 +46,7 @@ class MetricCoordinateSystem: public graphicsUtils::AbstractCoordinateSystem /// Converting pixels to QPointF QPointF toUnit(const QPointF &size) const override; private: - // Doesn't take ownership, ownership is twoDModel::model::Settings. - // The lifetime of this object is greater than MetricCoordinateSystem (see Model.h) - QPointer mMetricSystem; + QSharedPointer mMetricSystem; }; } diff --git a/plugins/robots/common/twoDModel/include/twoDModel/engine/model/metricSystem.h b/plugins/robots/common/twoDModel/include/twoDModel/engine/model/metricSystem.h index ea86e900ef..1f500a8e23 100644 --- a/plugins/robots/common/twoDModel/include/twoDModel/engine/model/metricSystem.h +++ b/plugins/robots/common/twoDModel/include/twoDModel/engine/model/metricSystem.h @@ -24,10 +24,8 @@ namespace twoDModel { namespace model { /// Incapsulates size unit settings used by 2D model. -class TWO_D_MODEL_EXPORT SizeUnit : public QObject +class TWO_D_MODEL_EXPORT SizeUnit { - Q_OBJECT - public: /// Possible units of measurement enum class Unit { @@ -42,6 +40,8 @@ class TWO_D_MODEL_EXPORT SizeUnit : public QObject /// The current pixel value in centimeters qreal pixelsInCm() const; + twoDModel::model::SizeUnit::Unit unit() const; + /// Serialize the sizeUnit in the WorldModel void serialize(QDomElement &parent) const; @@ -49,7 +49,7 @@ class TWO_D_MODEL_EXPORT SizeUnit : public QObject void deserialize(const QDomElement &parent); /// Set the current unit of measurement - void setUnit(twoDModel::model::SizeUnit::Unit unit); + void setSizeUnit(twoDModel::model::SizeUnit::Unit unit); /// Multiplier for conversion to pixels qreal countFactor() const; @@ -60,14 +60,9 @@ class TWO_D_MODEL_EXPORT SizeUnit : public QObject /// Get current unit string representation QString toStr() const; - std::map currentValues() const; - - Unit defaultUnit() const; - -Q_SIGNALS: - /// Emit when the sizeUnit is serialized - void sizeUnitChanged(const twoDModel::model::SizeUnit::Unit &unit); + static std::map currentValues(); + static Unit defaultUnit(); private: Unit mSizeUnit { Unit::Pixels }; qreal mPixelsInCm { twoDModel::pixelsInCm }; diff --git a/plugins/robots/common/twoDModel/include/twoDModel/engine/model/settings.h b/plugins/robots/common/twoDModel/include/twoDModel/engine/model/settings.h index f08662852c..10ee45062d 100644 --- a/plugins/robots/common/twoDModel/include/twoDModel/engine/model/settings.h +++ b/plugins/robots/common/twoDModel/include/twoDModel/engine/model/settings.h @@ -15,7 +15,7 @@ #pragma once #include -#include "metricSystem.h" +#include #include "twoDModel/twoDModelDeclSpec.h" class QDomElement; @@ -23,6 +23,8 @@ class QDomElement; namespace twoDModel { namespace model { +class SizeUnit; + /// Incapsulates settings used by 2D model. class TWO_D_MODEL_EXPORT Settings : public QObject { @@ -37,10 +39,6 @@ class TWO_D_MODEL_EXPORT Settings : public QObject /// Returns true is user wants to add some noise to sensors values. bool realisticSensors() const; - /// To simplify the already overloaded WorldModel xml, - /// it was decided to use a tag in the existing tag - SizeUnit *sizeUnit(); - qreal pixelsInCm() const; /// Returns true is user wants to add some noise to motors work. @@ -56,17 +54,22 @@ class TWO_D_MODEL_EXPORT Settings : public QObject void setRealisticMotors(bool set); - SizeUnit *sizeUnit() const; + QSharedPointer sizeUnit() const; Q_SIGNALS: /// Emitted each time when user modifies physical preferences. void physicsChanged(bool isRealistic); + /// Emit when the sizeUnit is serialized + void sizeUnitChanged(const QSharedPointer &unit); + + void gridSizeChanged(qreal size); + private: bool mRealisticPhysics { false }; bool mRealisticSensors { false }; bool mRealisticMotors { false }; - QScopedPointer mSizeUnitSystem; + QSharedPointer mSizeUnitSystem; }; } diff --git a/plugins/robots/common/twoDModel/include/twoDModel/engine/view/twoDModelWidget.h b/plugins/robots/common/twoDModel/include/twoDModel/engine/view/twoDModelWidget.h index 44ad2a8dca..d804f071ba 100644 --- a/plugins/robots/common/twoDModel/include/twoDModel/engine/view/twoDModelWidget.h +++ b/plugins/robots/common/twoDModel/include/twoDModel/engine/view/twoDModelWidget.h @@ -50,6 +50,7 @@ namespace twoDModel { namespace model { class Model; class RobotModel; +class SizeUnit; } namespace view { @@ -176,8 +177,7 @@ private Q_SLOTS: void trainingModeChanged(bool enabled); void updateUIPhysicsSettings(); - void updateRobotInfoWidget(const qreal factor, const QString& unitString); - + void updateRobotInfoWidget(const QSharedPointer &sizeUnit); private: enum CursorType { diff --git a/plugins/robots/common/twoDModel/src/engine/items/colorFieldItem.h b/plugins/robots/common/twoDModel/src/engine/items/colorFieldItem.h index fbe89313ca..74355f9a50 100644 --- a/plugins/robots/common/twoDModel/src/engine/items/colorFieldItem.h +++ b/plugins/robots/common/twoDModel/src/engine/items/colorFieldItem.h @@ -17,10 +17,6 @@ namespace twoDModel { -namespace model { -class SizeUnit; -} - namespace items { class ColorFieldItem: public view::TwoDSceneItem diff --git a/plugins/robots/common/twoDModel/src/engine/items/imageItem.cpp b/plugins/robots/common/twoDModel/src/engine/items/imageItem.cpp index 9345ccfd3f..b5ab8e11f4 100644 --- a/plugins/robots/common/twoDModel/src/engine/items/imageItem.cpp +++ b/plugins/robots/common/twoDModel/src/engine/items/imageItem.cpp @@ -25,7 +25,7 @@ using namespace qReal; using namespace graphicsUtils; ImageItem::ImageItem(graphicsUtils::AbstractCoordinateSystem *metricSystem, - const QSharedPointer &image, QRect geometry) + const QSharedPointer &image, const QRectF &geometry) : mImage(image) { setCoordinateSystem(metricSystem); @@ -44,7 +44,7 @@ ImageItem::ImageItem(graphicsUtils::AbstractCoordinateSystem *metricSystem, AbstractItem *ImageItem::clone() const { - const auto cloned = new ImageItem(coordinateSystem(), mImage, QRect(x1(), y1(), x2() - x1(), y2() - y1())); + const auto cloned = new ImageItem(coordinateSystem(), mImage, QRectF(x1(), y1(), x2() - x1(), y2() - y1())); AbstractItem::copyTo(cloned); return cloned; } @@ -90,7 +90,7 @@ QRectF ImageItem::boundingRect() const QRectF ImageItem::calcNecessaryBoundingRect() const { - return QRectF(qMin(x1(), x2()), qMin(y1(), y2()), qAbs(x2() - x1()), qAbs(y2() - y1())); + return {qMin(x1(), x2()), qMin(y1(), y2()), qAbs(x2() - x1()), qAbs(y2() - y1())}; } void ImageItem::drawItem(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -232,10 +232,10 @@ QRectF ImageItem::deserializeRect(const QString &string) const const auto y = splittedStr[1].toDouble(); const auto w = splittedStr[2].toDouble(); const auto h = splittedStr[3].toDouble(); - return QRectF(x, y, w, h); + return {x, y, w, h}; } - return QRectF(); + return {}; } void ImageItem::resizeItem(QGraphicsSceneMouseEvent *event) @@ -250,7 +250,7 @@ void ImageItem::resizeItem(QGraphicsSceneMouseEvent *event) } } else if (dragState() != None) { setFlag(QGraphicsItem::ItemIsMovable, false); - const auto gridSize = SettingsManager::value("2dGridCellSize").toInt(); + const auto gridSize = SettingsManager::value("2dDoubleGridCellSize").toReal(); const auto x = alignedCoordinate(event->scenePos().x(), gridSize); const auto y = alignedCoordinate(event->scenePos().y(), gridSize); setXYWithDragState(mapFromScene(x, y)); @@ -261,7 +261,7 @@ void ImageItem::resizeItem(QGraphicsSceneMouseEvent *event) // and align top left corner to grid QRectF itemBoundingRect = calcNecessaryBoundingRect(); const auto topLeft = mapToScene(QPointF(itemBoundingRect.left(), itemBoundingRect.top())); - const auto gridSize = SettingsManager::value("2dGridCellSize").toInt(); + const auto gridSize = SettingsManager::value("2dDoubleGridCellSize").toReal(); const auto x = alignedCoordinate(topLeft.x(), gridSize); const auto y = alignedCoordinate(topLeft.y(), gridSize); auto delta = QPointF(x, y) - topLeft; diff --git a/plugins/robots/common/twoDModel/src/engine/items/imageItem.h b/plugins/robots/common/twoDModel/src/engine/items/imageItem.h index 40544c4528..8565b6d7d9 100644 --- a/plugins/robots/common/twoDModel/src/engine/items/imageItem.h +++ b/plugins/robots/common/twoDModel/src/engine/items/imageItem.h @@ -33,7 +33,7 @@ class ImageItem : public graphicsUtils::AbstractItem public: ImageItem(graphicsUtils::AbstractCoordinateSystem *metricSystem, - const QSharedPointer &image, QRect geometry); + const QSharedPointer &image, const QRectF &geometry); AbstractItem *clone() const; @@ -45,7 +45,7 @@ class ImageItem : public graphicsUtils::AbstractItem QRectF boundingRect() const override; QRectF calcNecessaryBoundingRect() const override; - void drawItem(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; + void drawItem(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void drawExtractionForItem(QPainter* painter) override; QPainterPath resizeArea() const override; void resizeItem(QGraphicsSceneMouseEvent *event) override; diff --git a/plugins/robots/common/twoDModel/src/engine/items/wallItem.cpp b/plugins/robots/common/twoDModel/src/engine/items/wallItem.cpp index 97262da765..ab24afeefb 100644 --- a/plugins/robots/common/twoDModel/src/engine/items/wallItem.cpp +++ b/plugins/robots/common/twoDModel/src/engine/items/wallItem.cpp @@ -51,7 +51,7 @@ WallItem::WallItem(graphicsUtils::AbstractCoordinateSystem *metricSystem, WallItem *WallItem::clone() const { - WallItem * const cloned = new WallItem(coordinateSystem(), {x1(), y1()}, {x2(), y2()}); + auto * const cloned = new WallItem(coordinateSystem(), {x1(), y1()}, {x2(), y2()}); AbstractItem::copyTo(cloned); connect(this, &AbstractItem::positionChanged, cloned, &WallItem::recalculateBorders); connect(this, &AbstractItem::x1Changed, cloned, &WallItem::recalculateBorders); @@ -65,7 +65,7 @@ WallItem *WallItem::clone() const QAction *WallItem::wallTool() { - QAction * const result = new QAction(QIcon(":/icons/2d_wall.png"), tr("Wall (W)"), nullptr); + auto * const result = new QAction(QIcon(":/icons/2d_wall.png"), tr("Wall (W)"), nullptr); result->setShortcuts({QKeySequence(Qt::Key_W), QKeySequence(Qt::Key_2)}); result->setCheckable(true); return result; @@ -175,8 +175,8 @@ void WallItem::deserialize(const QDomElement &element) setY2(end.y()); readPenBrush(element); - if (pen().widthF()) { - mWallWidth = pen().widthF(); + if (pen().width()) { + mWallWidth = pen().width(); } SolidItem::deserialize(element); @@ -190,7 +190,8 @@ QPainterPath WallItem::path() const void WallItem::recalculateBorders() { - mPath = mLineImpl.shape(mWallWidth, begin().x(), begin().y(), end().x(), end().y()); + /// TODO: Fix narrowing conversion + mPath = mLineImpl.shape(static_cast(mWallWidth), begin().x(), begin().y(), end().x(), end().y()); } void WallItem::resizeItem(QGraphicsSceneMouseEvent *event) @@ -202,7 +203,7 @@ void WallItem::resizeItem(QGraphicsSceneMouseEvent *event) reshapeRectWithShift(); } else { if (SettingsManager::value("2dShowGrid").toBool() && event->modifiers() != Qt::ControlModifier) { - resizeWithGrid(event, SettingsManager::value("2dGridCellSize").toInt()); + resizeWithGrid(event, SettingsManager::value("2dDoubleGridCellSize").toReal()); } else { if (dragState() == TopLeft || dragState() == BottomRight) { calcResizeItem(event); @@ -220,7 +221,8 @@ void WallItem::reshapeRectWithShift() const qreal differenceY = qAbs(y2() - y1()); const qreal differenceXY = qAbs(differenceX - differenceY); const qreal size = qMax(differenceX, differenceY); - const int delta = size / 2; + /// TODO: Fix narrowing conversion + const int delta = static_cast(size / 2); if (differenceXY > delta) { const qreal corner1X = dragState() == TopLeft ? x2() : x1(); const qreal corner1Y = dragState() == TopLeft ? y2() : y1(); @@ -247,7 +249,7 @@ void WallItem::reshapeRectWithShift() } } -void WallItem::resizeWithGrid(QGraphicsSceneMouseEvent *event, int indexGrid) +void WallItem::resizeWithGrid(QGraphicsSceneMouseEvent *event, qreal gridSize) { const qreal x = mapFromScene(event->scenePos()).x(); const qreal y = mapFromScene(event->scenePos()).y(); @@ -257,31 +259,31 @@ void WallItem::resizeWithGrid(QGraphicsSceneMouseEvent *event, int indexGrid) if (dragState() == TopLeft) { setX1(x); setY1(y); - reshapeBeginWithGrid(indexGrid); + reshapeBeginWithGrid(gridSize); } else if (dragState() == BottomRight) { setX2(x); setY2(y); - reshapeEndWithGrid(indexGrid); + reshapeEndWithGrid(gridSize); } else { setPos(mEstimatedPos); - moveBy(alignedCoordinate(begin().x(), indexGrid) - begin().x() - , alignedCoordinate(begin().y(), indexGrid) - begin().y()); + moveBy(alignedCoordinate(begin().x(), gridSize) - begin().x() + , alignedCoordinate(begin().y(), gridSize) - begin().y()); } } -void WallItem::reshapeEndWithGrid(int indexGrid) +void WallItem::reshapeEndWithGrid(qreal gridSize) { - setX2(alignedCoordinate(end().x(), indexGrid) - pos().x()); - setY2(alignedCoordinate(end().y(), indexGrid) - pos().y()); + setX2(alignedCoordinate(end().x(), gridSize) - pos().x()); + setY2(alignedCoordinate(end().y(), gridSize) - pos().y()); } -void WallItem::reshapeBeginWithGrid(int indexGrid) +void WallItem::reshapeBeginWithGrid(qreal gridSize) { - setX1(alignedCoordinate(begin().x(), indexGrid) - pos().x()); - setY1(alignedCoordinate(begin().y(), indexGrid) - pos().y()); + setX1(alignedCoordinate(begin().x(), gridSize) - pos().x()); + setY1(alignedCoordinate(begin().y(), gridSize) - pos().y()); } -void WallItem::alignTheWall(int indexGrid) +void WallItem::alignTheWall(qreal indexGrid) { reshapeBeginWithGrid(indexGrid); reshapeEndWithGrid(indexGrid); diff --git a/plugins/robots/common/twoDModel/src/engine/items/wallItem.h b/plugins/robots/common/twoDModel/src/engine/items/wallItem.h index e71c20e0e0..6775d4ae51 100644 --- a/plugins/robots/common/twoDModel/src/engine/items/wallItem.h +++ b/plugins/robots/common/twoDModel/src/engine/items/wallItem.h @@ -58,12 +58,12 @@ class WallItem : public graphicsUtils::AbstractItem, public SolidItem QPainterPath path() const; - void resizeWithGrid(QGraphicsSceneMouseEvent *event, int indexGrid); + void resizeWithGrid(QGraphicsSceneMouseEvent *event, qreal gridSize); - void reshapeEndWithGrid(int indexGrid); - void reshapeBeginWithGrid(int indexGrid); + void reshapeEndWithGrid(qreal indexGrid); + void reshapeBeginWithGrid(qreal indexGrid); void setDraggedEnd(qreal x, qreal y); - void alignTheWall(int indexGrid); + void alignTheWall(qreal indexGrid); QPolygonF collidingPolygon() const override; BodyType bodyType() const override; @@ -79,7 +79,7 @@ class WallItem : public graphicsUtils::AbstractItem, public SolidItem const QImage mImage; QPainterPath mPath; - qreal mWallWidth {10}; + int mWallWidth {10}; QPointF mEstimatedPos; }; diff --git a/plugins/robots/common/twoDModel/src/engine/model/metricCoordinateSystem.cpp b/plugins/robots/common/twoDModel/src/engine/model/metricCoordinateSystem.cpp index 833baa490a..5c7408b1bb 100644 --- a/plugins/robots/common/twoDModel/src/engine/model/metricCoordinateSystem.cpp +++ b/plugins/robots/common/twoDModel/src/engine/model/metricCoordinateSystem.cpp @@ -19,20 +19,18 @@ using namespace twoDModel::model; MetricCoordinateSystem::MetricCoordinateSystem( - twoDModel::model::SizeUnit *metricSystem, + const QSharedPointer &metricSystem, QObject* parent) : graphicsUtils::AbstractCoordinateSystem(parent) , mMetricSystem(metricSystem) { } -MetricCoordinateSystem::~MetricCoordinateSystem() -{ -} +MetricCoordinateSystem::~MetricCoordinateSystem() = default; qreal MetricCoordinateSystem::toPx(const qreal size) const { - if (mMetricSystem.isNull()) { + if (!mMetricSystem) { return size; } @@ -41,7 +39,7 @@ qreal MetricCoordinateSystem::toPx(const qreal size) const qreal MetricCoordinateSystem::toUnit(const qreal size) const { - if (mMetricSystem.isNull()) { + if (!mMetricSystem) { return size; } diff --git a/plugins/robots/common/twoDModel/src/engine/model/metricSystem.cpp b/plugins/robots/common/twoDModel/src/engine/model/metricSystem.cpp index 9b3923fe02..96fdccdc63 100644 --- a/plugins/robots/common/twoDModel/src/engine/model/metricSystem.cpp +++ b/plugins/robots/common/twoDModel/src/engine/model/metricSystem.cpp @@ -13,42 +13,46 @@ * limitations under the License. */ #include - #include "twoDModel/engine/model/metricSystem.h" using namespace twoDModel::model; namespace { - /// Translation of a string representation into a unit - static SizeUnit::Unit stringToUnit(const QString &unit) { - if (unit.isEmpty()) { - return SizeUnit::Unit::Pixels; - } - if (unit == "cm") { - return SizeUnit::Unit::Centimeters; - } - if (unit == "mm") { - return SizeUnit::Unit::Millimeters; - } - if (unit == "m") { - return SizeUnit::Unit::Meters; - } +/// Translation of a string representation into a unit +SizeUnit::Unit stringToUnit(const QString &unit) { + if (unit.isEmpty()) { return SizeUnit::Unit::Pixels; } + if (unit == "cm") { + return SizeUnit::Unit::Centimeters; + } + if (unit == "mm") { + return SizeUnit::Unit::Millimeters; + } + if (unit == "m") { + return SizeUnit::Unit::Meters; + } + return SizeUnit::Unit::Pixels; +} - /// Translation of a unit into a string representation - static QString unitToString(SizeUnit::Unit unit) { - if (unit == SizeUnit::Unit::Centimeters) { - return "cm"; - } - if (unit == SizeUnit::Unit::Millimeters) { - return "mm"; - } - if (unit == SizeUnit::Unit::Meters) { - return "m"; - } - return {}; +/// Translation of a unit into a string representation +QString unitToString(SizeUnit::Unit unit) { + if (unit == SizeUnit::Unit::Centimeters) { + return "cm"; + } + if (unit == SizeUnit::Unit::Millimeters) { + return "mm"; } + if (unit == SizeUnit::Unit::Meters) { + return "m"; + } + return {}; +} +} + +SizeUnit::Unit SizeUnit::unit() const +{ + return mSizeUnit; } qreal SizeUnit::pixelsInCm() const @@ -67,14 +71,13 @@ void SizeUnit::serialize(QDomElement &parent) const void SizeUnit::deserialize(const QDomElement &parent) { if (!parent.isNull()) { - setUnit(stringToUnit(parent.attribute("sizeUnit", ""))); + setSizeUnit(stringToUnit(parent.attribute("sizeUnit", ""))); } else { - setUnit(defaultUnit()); + setSizeUnit(defaultUnit()); } - Q_EMIT sizeUnitChanged(mSizeUnit); } -void SizeUnit::setUnit(twoDModel::model::SizeUnit::Unit unit) +void SizeUnit::setSizeUnit(twoDModel::model::SizeUnit::Unit unit) { mSizeUnit = unit; } @@ -110,27 +113,28 @@ qreal SizeUnit::toPx(const qreal size) const QString SizeUnit::toStr() const { if (mSizeUnit == SizeUnit::Unit::Centimeters) { - return tr("cm"); + return QObject::tr("cm"); } if (mSizeUnit == SizeUnit::Unit::Millimeters) { - return tr("mm"); + return QObject::tr("mm"); } if (mSizeUnit == SizeUnit::Unit::Meters) { - return tr("m"); + return QObject::tr("m"); } - return tr("px"); + return QObject::tr("px"); } -std::map SizeUnit::currentValues() const +std::map SizeUnit::currentValues() { return { - {tr("Pixels"), Unit::Pixels } - , {tr("Centimeters"), Unit::Centimeters} - , {tr("Meters"), Unit::Meters} - , {tr("Millimeters"), Unit::Millimeters} + {QObject::tr("Pixels"), Unit::Pixels } + , {QObject::tr("Centimeters"), Unit::Centimeters} + , {QObject::tr("Meters"), Unit::Meters} + , {QObject::tr("Millimeters"), Unit::Millimeters} }; } -SizeUnit::Unit SizeUnit::defaultUnit() const { +SizeUnit::Unit SizeUnit::defaultUnit() +{ return Unit::Pixels; } diff --git a/plugins/robots/common/twoDModel/src/engine/model/settings.cpp b/plugins/robots/common/twoDModel/src/engine/model/settings.cpp index add10634a1..075f549aeb 100644 --- a/plugins/robots/common/twoDModel/src/engine/model/settings.cpp +++ b/plugins/robots/common/twoDModel/src/engine/model/settings.cpp @@ -13,16 +13,15 @@ * limitations under the License. */ #include - -#include "twoDModel/engine/model/settings.h" - #include +#include "twoDModel/engine/model/settings.h" +#include "twoDModel/engine/model/metricSystem.h" using namespace twoDModel::model; Settings::Settings(QObject *parent) : QObject(parent) - , mSizeUnitSystem(new SizeUnit()) + , mSizeUnitSystem(new SizeUnit()) {} bool Settings::realisticPhysics() const @@ -40,11 +39,6 @@ qreal Settings::pixelsInCm() const return mSizeUnitSystem->pixelsInCm(); } -SizeUnit *Settings::sizeUnit() -{ - return mSizeUnitSystem.data(); -} - bool Settings::realisticMotors() const { return mRealisticMotors; @@ -58,6 +52,9 @@ void Settings::serialize(QDomElement &parent) const result.setAttribute("realisticSensors", mRealisticSensors ? "true" : "false"); result.setAttribute("realisticMotors", mRealisticMotors ? "true" : "false"); mSizeUnitSystem->serialize(result); + const auto currentGridSize = qReal::SettingsManager::value("2dDoubleGridCellSize") + .toReal() / mSizeUnitSystem->countFactor(); + result.setAttribute("gridCellSize", QString::number(currentGridSize)); } void Settings::deserialize(const QDomElement &parent) @@ -67,6 +64,20 @@ void Settings::deserialize(const QDomElement &parent) mRealisticMotors = parent.attribute("realisticMotors") == "true"; mSizeUnitSystem->deserialize(parent); Q_EMIT physicsChanged(mRealisticPhysics); + Q_EMIT sizeUnitChanged(mSizeUnitSystem); + if (parent.hasAttribute("gridCellSize")) { + const auto gridSize = parent.attribute("gridCellSize").toDouble(); + // TODO: Synchronize with GridParamters.h + constexpr auto minimalSize = 10; + constexpr auto maximumSize = 150; + if (mSizeUnitSystem->toPx(gridSize) >= minimalSize + && mSizeUnitSystem->toPx(gridSize) <= maximumSize) { + Q_EMIT gridSizeChanged(gridSize); + return; + } + } + const auto gridSize = qReal::SettingsManager::value("2dDefaultGridCellSize", "50").toReal(); + Q_EMIT gridSizeChanged(gridSize); } void Settings::setRealisticPhysics(bool set) @@ -85,7 +96,7 @@ void Settings::setRealisticMotors(bool set) mRealisticMotors = set; } -SizeUnit *Settings::sizeUnit() const +QSharedPointer Settings::sizeUnit() const { - return mSizeUnitSystem.data(); + return mSizeUnitSystem; } diff --git a/plugins/robots/common/twoDModel/src/engine/view/parts/gridParameters.cpp b/plugins/robots/common/twoDModel/src/engine/view/parts/gridParameters.cpp index 3b14eec2d8..0d65cceaf4 100644 --- a/plugins/robots/common/twoDModel/src/engine/view/parts/gridParameters.cpp +++ b/plugins/robots/common/twoDModel/src/engine/view/parts/gridParameters.cpp @@ -13,51 +13,82 @@ * limitations under the License. */ #include "gridParameters.h" - #include #include - +#include "twoDModel/engine/model/metricSystem.h" #include using namespace twoDModel::view; +namespace { + constexpr auto minLE = 10; + constexpr auto maxLE = 150; + constexpr auto scale = 10000.0f; +} + GridParameters::GridParameters(QWidget *parent) : QFrame(parent) { - QHBoxLayout *layout = new QHBoxLayout(this); - + auto *layout = new QHBoxLayout(this); mShowGridCheckBox = new QCheckBox(this); mShowGridCheckBox->setText(tr("Grid")); mShowGridCheckBox->setTristate(false); - mCellSize = new QSlider(this); mCellSize->setOrientation(Qt::Horizontal); - mCellSize->setMinimum(50); - mCellSize->setMaximum(200); - mCellSize->setTickInterval(10); + mCellSize->setMinimum(minLE * scale); + mCellSize->setMaximum(maxLE * scale); + mCellSize->setSingleStep(0.1 * scale); + mCellSize->setPageStep(scale); mCellSize->setEnabled(false); layout->addWidget(mShowGridCheckBox); layout->addWidget(mCellSize); layout->setContentsMargins(5, 5, 5, 5); - connect(mShowGridCheckBox, SIGNAL(toggled(bool)), mCellSize, SLOT(setEnabled(bool))); - connect(mShowGridCheckBox, SIGNAL(toggled(bool)), this, SLOT(showGrid(bool))); - connect(mCellSize, SIGNAL(valueChanged(int)), this, SLOT(setCellSize(int))); + connect(mShowGridCheckBox, &QAbstractButton::toggled, mCellSize, &QWidget::setEnabled); + connect(mShowGridCheckBox, &QAbstractButton::toggled, this, &GridParameters::showGrid); + connect(mCellSize, &QAbstractSlider::valueChanged, this, &GridParameters::setCellSize); const bool showGrid = qReal::SettingsManager::value("2dShowGrid").toBool(); - const int gridSize = qReal::SettingsManager::value("2dGridCellSize").toInt(); + const qreal gridSize = qReal::SettingsManager::value("2dDefaultGridCellSize").toReal(); mShowGridCheckBox->setChecked(showGrid); - mCellSize->setValue(gridSize); - + mCellSize->setValue(qRound(gridSize * scale)); setLayout(layout); + // Bring the slider values closer to the step values (which should ideally be 0.1 of the unit of measurement) + connect(mCellSize, &QSlider::sliderMoved, this, [this](int rawValue) { + const auto step = mCellSize->singleStep(); + const auto snapped = qRound(static_cast(rawValue) / step) * step; + if (snapped != rawValue) { + mCellSize->setValue(snapped); + } + }); } -GridParameters::~GridParameters() +void GridParameters::onSizeUnitChanged(const QSharedPointer &unit) { + mSizeUnit = unit; + mCellSize->blockSignals(true); + const auto factor = unit->countFactor(); + // We adapt the slider to the coordinate system in such a way as to cover the desired range of values. + // Thus, with the selected millimeters, the range will be from 35000 to 525000, which corresponds + // to the size of the cell from 35 mm to 525 and allows you to set its size with an accuracy + // of a thousandth of a millimeter. mCellSize->setSingleStep(0.1 * scale) means that for the selected system, + // the step will be 1000 units. In other words, 0.1 of the selected measurement system + mCellSize->setMinimum(qRound((minLE / factor) * scale)); + mCellSize->setMaximum(qRound((maxLE / factor) * scale)); + const qreal currentGlobal = qReal::SettingsManager::value("2dDoubleGridCellSize").toReal(); + mCellSize->setValue(qRound((currentGlobal / factor) * scale)); + mCellSize->blockSignals(false); } +void GridParameters::onGridParametersChangedOutside(qreal newCellSize) +{ + mCellSize->setValue(qRound(newCellSize * scale)); +} + +GridParameters::~GridParameters() = default; + void GridParameters::showGrid(bool isGridEnabled) { qReal::SettingsManager::setValue("2dShowGrid", isGridEnabled); @@ -66,6 +97,8 @@ void GridParameters::showGrid(bool isGridEnabled) void GridParameters::setCellSize(int cellSizeValue) { - qReal::SettingsManager::setValue("2dGridCellSize", cellSizeValue); + const auto factor = mSizeUnit ? mSizeUnit->countFactor() : 1.0; + const auto unitsValue = static_cast(cellSizeValue) * factor / scale; + qReal::SettingsManager::setValue("2dDoubleGridCellSize", unitsValue); Q_EMIT parametersChanged(); } diff --git a/plugins/robots/common/twoDModel/src/engine/view/parts/gridParameters.h b/plugins/robots/common/twoDModel/src/engine/view/parts/gridParameters.h index 0eb8b5515d..c5ce6c0641 100644 --- a/plugins/robots/common/twoDModel/src/engine/view/parts/gridParameters.h +++ b/plugins/robots/common/twoDModel/src/engine/view/parts/gridParameters.h @@ -19,6 +19,9 @@ #include namespace twoDModel { +namespace model { +class SizeUnit; +} namespace view { class GridParameters : public QFrame @@ -27,11 +30,13 @@ class GridParameters : public QFrame public: explicit GridParameters(QWidget *parent = nullptr); - ~GridParameters(); + ~GridParameters() override; public Q_SLOTS: void showGrid(bool isGridEnabled); void setCellSize(int cellSizeValue); + void onGridParametersChangedOutside(qreal newCellSize); + void onSizeUnitChanged(const QSharedPointer &unit); Q_SIGNALS: void parametersChanged(); @@ -39,6 +44,7 @@ public Q_SLOTS: private: QSlider *mCellSize; QCheckBox *mShowGridCheckBox; + QSharedPointer mSizeUnit; }; } diff --git a/plugins/robots/common/twoDModel/src/engine/view/parts/gridSizeWidget.cpp b/plugins/robots/common/twoDModel/src/engine/view/parts/gridSizeWidget.cpp new file mode 100644 index 0000000000..4a3c021337 --- /dev/null +++ b/plugins/robots/common/twoDModel/src/engine/view/parts/gridSizeWidget.cpp @@ -0,0 +1,117 @@ +/* Copyright 2026 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#include +#include +#include +#include +#include +#include "gridSizeWidget.h" +#include + +using namespace twoDModel::view; + +namespace { +constexpr auto pixelMinimalValue = 10.0; +constexpr auto pixelMaximumValue = 150.0; +} + +GridSizeWidget::~GridSizeWidget() = default; + +GridSizeWidget::GridSizeWidget(QWidget *parent) + : QWidget(parent) + , mUnit(nullptr) + , mStackedWidget(new QStackedWidget(this)) +{ + setupUI(); + createSpinBoxes(); +} + +void GridSizeWidget::createSpinBoxes() +{ + auto createSpinBoxLambda = [this](qreal step, int decimals, + twoDModel::model::SizeUnit::Unit unit) { + twoDModel::model::SizeUnit sizeUnit {}; + sizeUnit.setSizeUnit(unit); + auto *spinBox = new QDoubleSpinBox(this); + updateValues(spinBox, sizeUnit, step); + spinBox->setDecimals(decimals); + mSlubSpinBoxes.emplace(unit, spinBox); + mStackedWidget->addWidget(spinBox); + connect(spinBox, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &GridSizeWidget::gridSizeChanged); + }; + + // Create custom Pixels SpinBox + createSpinBoxLambda(0.1, 3, twoDModel::model::SizeUnit::Unit::Pixels); + // Create custom Millimiter SpinBox + createSpinBoxLambda(0.1, 3, twoDModel::model::SizeUnit::Unit::Millimeters); + // Create custom Centimeter SpinBox + createSpinBoxLambda(0.1, 3, twoDModel::model::SizeUnit::Unit::Centimeters); + // Create custom Meter SpinBox + createSpinBoxLambda(0.05, 3, twoDModel::model::SizeUnit::Unit::Meters); + + mStackedWidget->setCurrentWidget(mSlubSpinBoxes[twoDModel::model::SizeUnit::defaultUnit()]); +} + +void GridSizeWidget::updateValues(QObject *spinBox, + twoDModel::model::SizeUnit sizeUnit, + qreal step) { + const auto displayMin = pixelMinimalValue / sizeUnit.countFactor(); + const auto displayMax = pixelMaximumValue / sizeUnit.countFactor(); + spinBox->setProperty("minimum", displayMin); + spinBox->setProperty("maximum", displayMax); + spinBox->setProperty("suffix", " " +sizeUnit.toStr()); + spinBox->setProperty("singleStep", step); +} + +void GridSizeWidget::setupUI() +{ + auto *layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(mStackedWidget); +} + +qreal GridSizeWidget::countFactor() +{ + return mUnit ? mUnit->countFactor() : 1.0f; +} + +void GridSizeWidget::onSizeUnitChanged(const QSharedPointer &unit) +{ + blockSignals(true); + mUnit = unit; + const auto it = mSlubSpinBoxes.find(mUnit->unit()); + if (it != mSlubSpinBoxes.end() && it->second != mStackedWidget->currentWidget()) { + mStackedWidget->setCurrentWidget(it->second); + setValue(it->second); + } + blockSignals(false); +} + +void GridSizeWidget::onGridParameterChanged() +{ + blockSignals(true); + setValue(mStackedWidget->currentWidget()); + blockSignals(false); +} + +void GridSizeWidget::setValue(QObject *currentSpinBox) +{ + if (!currentSpinBox) { + return; + } + const auto gridSize = qReal::SettingsManager::value("2dDoubleGridCellSize").toReal(); + currentSpinBox->setProperty("value", gridSize / countFactor()); +} diff --git a/plugins/robots/common/twoDModel/src/engine/view/parts/gridSizeWidget.h b/plugins/robots/common/twoDModel/src/engine/view/parts/gridSizeWidget.h new file mode 100644 index 0000000000..cbdaf16c1e --- /dev/null +++ b/plugins/robots/common/twoDModel/src/engine/view/parts/gridSizeWidget.h @@ -0,0 +1,51 @@ +/* Copyright 2025 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#pragma once +#include +#include +#include "twoDModel/engine/model/metricSystem.h" +#include + +class QStackedWidget; + +namespace twoDModel { +namespace view { + +/// A class that represents a set of QDoubleSpinBox's for different units of measurement, +/// as they may require different sinlgeSterp, suffix, and other parameters. +class GridSizeWidget : public QWidget +{ + Q_OBJECT +public: + explicit GridSizeWidget(QWidget *parent = nullptr); + ~GridSizeWidget() override; +public Q_SLOTS: + void onSizeUnitChanged(const QSharedPointer &unit); + void onGridParameterChanged(); +Q_SIGNALS: + void gridSizeChanged(qreal size); +private: + void setupUI(); + qreal countFactor(); + static void updateValues(QObject *spinBox, twoDModel::model::SizeUnit sizeUnit, qreal step); + void setValue(QObject *currentSpinBox); + void createSpinBoxes(); + QSharedPointer mUnit; + QStackedWidget *mStackedWidget; + std::unordered_map mSlubSpinBoxes; +}; + +} +} diff --git a/plugins/robots/common/twoDModel/src/engine/view/parts/ruler.cpp b/plugins/robots/common/twoDModel/src/engine/view/parts/ruler.cpp index 000a85a4eb..a8b0fd4787 100644 --- a/plugins/robots/common/twoDModel/src/engine/view/parts/ruler.cpp +++ b/plugins/robots/common/twoDModel/src/engine/view/parts/ruler.cpp @@ -13,38 +13,36 @@ * limitations under the License. */ #include "ruler.h" - #include #include #include #include +#include "twoDModel/engine/model/metricSystem.h" using namespace twoDModel::view; const qreal gap = 5; // The gap between the ruler borders and text on it. -const int frequency = 150; // The text on the ruler will not be met more often than once per this number of pixels. +const int frequency = 50; // The text on the ruler will not be met more often than once per this number of pixels. Ruler::Ruler(QWidget *parent) : QFrame(parent) , mOrientation(Qt::Horizontal) - , mMetricFactor(1.0) + , mSizeUnit(nullptr) { mFont.setPixelSize(8); } -Ruler::~Ruler() -{ -} +Ruler::~Ruler() = default; Qt::Orientation Ruler::orientation() const { return mOrientation; } -void Ruler::setMetricFactor(const qreal factor) +void Ruler::onSizeUnitChanged(const QSharedPointer &unit) { - mMetricFactor = factor; + mSizeUnit = unit; } void Ruler::setOrientation(Qt::Orientation orientation) @@ -54,9 +52,9 @@ void Ruler::setOrientation(Qt::Orientation orientation) const QString theLongestText = "-123.45"; // The longest text that ruler must place into itself. const QSizeF theLargestSize = textBoundingRect(theLongestText).size(); if (orientation == Qt::Horizontal) { - setFixedHeight(theLargestSize.height() + 2 * gap); + setFixedHeight(static_cast(theLargestSize.height() + 2 * gap)); } else { - setFixedWidth(theLargestSize.width() + 2 * gap); + setFixedWidth(static_cast(theLargestSize.width() + 2 * gap)); } } @@ -65,25 +63,37 @@ void Ruler::paintEvent(QPaintEvent *event) QFrame::paintEvent(event); QPainter painter(this); painter.setFont(mFont); - const int gridSize = qReal::SettingsManager::value("2dGridCellSize").toInt(); - const int shift = qMax(frequency / gridSize, 1); - const QRectF sceneRect = mView->mapToScene(mView->viewport()->geometry()).boundingRect(); - const int firstCell = qCeil(relevantCoordinate(sceneRect.topLeft())) / gridSize; - // This will let us always draw 0 near zero line for more persistent coordinates scrolling. - // Without making first cell being multiple of shift the first marker will be always upon the first - // line and that looks horrible when user scrolls the scene. - const int realFirstCell = firstCell / shift * shift * gridSize; - for (int coordinate = realFirstCell - ; coordinate < relevantCoordinate(sceneRect.bottomRight()) - ; coordinate += shift * gridSize) - { - const QString text = QString::number(coordinate / mMetricFactor); - const QRectF boundingRect = textBoundingRect(text); - const qreal relevantPosition = relevantCoordinate(mView->mapFromScene(makePoint(coordinate, 0))); - const QPointF position = drawingPoint(relevantPosition, boundingRect.size()); - const QPointF alignment = makePoint(relevantDimension(boundingRect.size()) / 2, 0); - - painter.drawText(position - boundingRect.topLeft() - alignment, text); + + const auto gridSize = qReal::SettingsManager::value("2dDoubleGridCellSize").toReal(); + const auto currentCountFactor = countFactor(); + const auto sceneRect = mView->mapToScene(mView->viewport()->geometry()).boundingRect(); + const auto startPos = relevantCoordinate(sceneRect.topLeft()); + const auto endPos = relevantCoordinate(sceneRect.bottomRight()); + + const auto zoom = mView->transform().m11(); + const auto skipCells = qMax(1, qCeil((frequency / zoom) / gridSize)); + const auto effectiveStep = skipCells * gridSize; + const auto startIdx = static_cast(std::floor(startPos / effectiveStep)); + const auto endIdx = static_cast(std::ceil(endPos / effectiveStep)); + + for (int i = startIdx; i <= endIdx; ++i) { + const qreal coordinate = i * effectiveStep; + QString text = QString::number(coordinate / currentCountFactor, 'f', 3); + if (text.contains('.')) { + while (text.endsWith('0')) { + text.chop(1); + } + if (text.endsWith('.')) { + text.chop(1); + } + } + const auto &boundingRect = textBoundingRect(text); + const auto relevantPosition = relevantCoordinate(mView->mapFromScene(makePoint(coordinate, 0))); + const auto position = drawingPoint(relevantPosition, boundingRect.size()); + const auto alignment = makePoint(relevantDimension(boundingRect.size()) / 2, 0); + if (relevantPosition >= 0 && relevantPosition <= relevantDimension(this->size())) { + painter.drawText(position - boundingRect.topLeft() - alignment, text); + } } } @@ -92,6 +102,14 @@ qreal Ruler::relevantCoordinate(QPointF point) const return orientation() == Qt::Horizontal ? point.x() : point.y(); } +qreal Ruler::countFactor() const +{ + if (mSizeUnit) { + return mSizeUnit->countFactor(); + } + return 1.0f; +} + qreal Ruler::relevantDimension(QSizeF size) const { return orientation() == Qt::Horizontal ? size.width() : size.height(); diff --git a/plugins/robots/common/twoDModel/src/engine/view/parts/ruler.h b/plugins/robots/common/twoDModel/src/engine/view/parts/ruler.h index b2fc53f3f8..36222aa773 100644 --- a/plugins/robots/common/twoDModel/src/engine/view/parts/ruler.h +++ b/plugins/robots/common/twoDModel/src/engine/view/parts/ruler.h @@ -19,6 +19,9 @@ class QGraphicsView; namespace twoDModel { +namespace model { +class SizeUnit; +} namespace view { /// A widget for displaying distances on grid in centimeters. @@ -30,7 +33,7 @@ class Ruler : public QFrame public: explicit Ruler(QWidget *parent = nullptr); - ~Ruler(); + ~Ruler() override; /// Returns the orientation of this ruler. Qt::Orientation orientation() const; @@ -39,24 +42,22 @@ public Q_SLOTS: /// Returns the orientation of this ruler. void setOrientation(Qt::Orientation orientation); - /// Reconfigures ruller to calculate distances in other metrics. The distance between grid lines in pixels - /// stays the same, but values in centimeters modified - void setMetricFactor(const qreal factor); + void onSizeUnitChanged(const QSharedPointer &unit); /// Configures this ruller to work with the given graphics view. void setScene(QGraphicsView *scene); - private: void paintEvent(QPaintEvent *event) override; qreal relevantCoordinate(QPointF point) const; + qreal countFactor() const; qreal relevantDimension(QSizeF size) const; qreal irrelevantDimension(QSizeF size) const; QPointF makePoint(qreal relevantCoordinate, qreal irrelevantCoordinate) const; QPointF drawingPoint(qreal relevantCoordinate, QSizeF textSize) const; QRectF textBoundingRect(const QString &text) const; Qt::Orientation mOrientation; - qreal mMetricFactor; + QSharedPointer mSizeUnit; QGraphicsView *mView {}; // Doesn`t take owership QFont mFont; }; diff --git a/plugins/robots/common/twoDModel/src/engine/view/scene/twoDModelScene.cpp b/plugins/robots/common/twoDModel/src/engine/view/scene/twoDModelScene.cpp index ed072d9b9d..7938d54ae1 100644 --- a/plugins/robots/common/twoDModel/src/engine/view/scene/twoDModelScene.cpp +++ b/plugins/robots/common/twoDModel/src/engine/view/scene/twoDModelScene.cpp @@ -823,7 +823,7 @@ void TwoDModelScene::drawBackground(QPainter *painter, const QRectF &rect) mWidthOfGrid = SettingsManager::value("GridWidth").toReal() / 100; painter->setPen(QPen(Qt::black, mWidthOfGrid)); QGraphicsScene::drawBackground(painter, rect); - const int cellSize = SettingsManager::value("2dGridCellSize").toInt(); + const qreal cellSize = SettingsManager::value("2dDoubleGridCellSize").toReal(); mGridDrawer.drawGrid(painter, rect, cellSize); drawAxes(painter); } @@ -888,9 +888,9 @@ void TwoDModelScene::addImage() , tr("Graphics (*.*)")); - const auto gridSize = SettingsManager::value("2dGridCellSize").toInt(); - const QPoint step(gridSize, gridSize); - QPoint topLeft = mainView()->mapToScene(0,0).toPoint() + step; + const auto gridSize = SettingsManager::value("2dDoubleGridCellSize").toReal(); + const QPointF step(gridSize, gridSize); + QPointF topLeft = mainView()->mapToScene(0,0).toPoint() + step; for (auto &&loadFileName : loadImages) { if (loadFileName.isEmpty()) { @@ -915,7 +915,7 @@ void TwoDModelScene::addImage() continue; } mDrawingAction = image; - const QRect rect(topLeft, size); + const QRectF rect(topLeft, size); QSharedPointer result(new twoDModel::items::ImageItem( &mModel.coordinateMetricSystem(), newImage, rect)); result->setMemorize(true); @@ -1019,8 +1019,8 @@ void TwoDModelScene::reshapeWall(QGraphicsSceneMouseEvent *event) mCurrentWall->setX2(pos.x()); mCurrentWall->setY2(pos.y()); if (SettingsManager::value("2dShowGrid").toBool()) { - mCurrentWall->reshapeBeginWithGrid(SettingsManager::value("2dGridCellSize").toInt()); - mCurrentWall->reshapeEndWithGrid(SettingsManager::value("2dGridCellSize").toInt()); + mCurrentWall->reshapeBeginWithGrid(SettingsManager::value("2dDoubleGridCellSize").toReal()); + mCurrentWall->reshapeEndWithGrid(SettingsManager::value("2dDoubleGridCellSize").toReal()); } else { if (event->modifiers() & Qt::ShiftModifier) { mCurrentWall->reshapeRectWithShift(); @@ -1148,7 +1148,7 @@ void TwoDModelScene::alignWalls() if (SettingsManager::value("2dShowGrid").toBool()) { for (auto &&wall : mModel.worldModel().walls()) { if (items().contains(wall.data())) { - wall->alignTheWall(SettingsManager::value("2dGridCellSize").toInt()); + wall->alignTheWall(SettingsManager::value("2dDoubleGridCellSize").toReal()); } } } diff --git a/plugins/robots/common/twoDModel/src/engine/view/twoDModelWidget.cpp b/plugins/robots/common/twoDModel/src/engine/view/twoDModelWidget.cpp index e35bc73778..ec038019f2 100644 --- a/plugins/robots/common/twoDModel/src/engine/view/twoDModelWidget.cpp +++ b/plugins/robots/common/twoDModel/src/engine/view/twoDModelWidget.cpp @@ -57,6 +57,7 @@ #include "twoDModel/engine/model/constants.h" #include "twoDModel/engine/model/twoDModelRobotParameters.h" #include "twoDModel/engine/model/model.h" +#include "twoDModel/engine/model/metricSystem.h" #include "nullTwoDModelDisplayWidget.h" #include @@ -145,13 +146,13 @@ TwoDModelWidget::TwoDModelWidget(Model &model, QWidget *parent) mUi->horizontalRuler->setScene(mUi->graphicsView); mUi->verticalRuler->setScene(mUi->graphicsView); + mUi->detailsTab->setParamsSettings(mUi->physicsParamsFrame); + mUi->detailsTab->setMetricSettings(mUi->metricFrame); - auto pixelsInCm = mModel.settings().pixelsInCm(); /// @todo: make some values editable + auto pixelsInCm = mModel.settings().pixelsInCm(); + connectMetricComboBoxes(); - mUi->detailsTab->setParamsSettings(mUi->physicsParamsFrame); - - updateRobotInfoWidget(pixelsInCm, tr("cm")); connect(&mModel, &model::Model::robotAdded, this, [this, pixelsInCm](){ auto robotModels = mModel.robotModels(); auto robotTrack = robotModels.isEmpty() || @@ -169,8 +170,10 @@ TwoDModelWidget::~TwoDModelWidget() delete mUi; } -void TwoDModelWidget::updateRobotInfoWidget(const qreal factor, const QString& unitString) +void TwoDModelWidget::updateRobotInfoWidget(const QSharedPointer &sizeUnit) { + const auto unitString = sizeUnit->toStr(); + const auto factor = sizeUnit->countFactor(); mUi->wheelDiamInCm->setValue(robotWheelDiameterInPx / factor); mUi->wheelDiameterUnit->setText(unitString); mUi->wheelDiamInCm->setButtonSymbols(QAbstractSpinBox::NoButtons); @@ -271,6 +274,12 @@ void TwoDModelWidget::initWidget() connect(mUi->editorModeButton, &QPushButton::toggled, &*mScene, &TwoDModelScene::onEditorModeToggled); connect(mUi->gridParametersBox, &twoDModel::view::GridParameters::parametersChanged , &*mScene, [&]() { mScene->update(); }); + connect(&mModel.settings(), &Settings::gridSizeChanged, + mUi->gridParametersBox, &GridParameters::onGridParametersChangedOutside); + connect(mUi->gridSizeWidget, &GridSizeWidget::gridSizeChanged, + mUi->gridParametersBox, &GridParameters::onGridParametersChangedOutside); + connect(mUi->gridParametersBox, &twoDModel::view::GridParameters::parametersChanged, + mUi->gridSizeWidget, &GridSizeWidget::onGridParameterChanged); connect(mUi->gridParametersBox, &GridParameters::parametersChanged, this, toggleRulers); connect(mUi->gridParametersBox, &twoDModel::view::GridParameters::parametersChanged , mUi->horizontalRuler, [&]() {mUi->horizontalRuler->update(); }); @@ -852,6 +861,7 @@ void TwoDModelWidget::setInteractivityFlags(ReadOnlyFlags flags) mRobotPositionReadOnly = flags.testFlag(ReadOnly::RobotPosition); if (mRobotPositionReadOnly) returnToStartMarker(); + mUi->metricComboBox->setVisible(!worldReadOnly); mScene->setInteractivityFlags(flags); } @@ -1084,31 +1094,34 @@ bool TwoDModelWidget::setSelectedValue(QComboBox * const comboBox, const T &port void TwoDModelWidget::connectMetricComboBoxes() { - connect(mModel.settings().sizeUnit(), &SizeUnit::sizeUnitChanged - , this, [=](SizeUnit::Unit unit) { - setSelectedValue(mUi->metricComboBox, unit); - }); - - connect(mUi->metricComboBox, QOverload::of(&QComboBox::currentIndexChanged) - , this, [this](int index) { - const auto unitValue = mUi->metricComboBox->itemData(index) - .value(); - const auto sizeUnit = mModel.settings().sizeUnit(); - sizeUnit->setUnit(unitValue); - const auto realValue = sizeUnit->countFactor(); - mUi->horizontalRuler->setMetricFactor(realValue); - mUi->verticalRuler->setMetricFactor(realValue); - updateRobotInfoWidget(realValue, sizeUnit->toStr()); - Q_EMIT mUi->gridParametersBox->parametersChanged(); + connect(&mModel.settings(), &Settings::sizeUnitChanged, this, [this] + (const QSharedPointer &unit) { + setSelectedValue(mUi->metricComboBox, unit->unit()); }); const auto sizeUnit = mModel.settings().sizeUnit(); const auto availableUnits = sizeUnit->currentValues(); for (auto &&availableUnit : availableUnits) { - mUi->metricComboBox->addItem(availableUnit.first, - QVariant::fromValue(availableUnit.second)); + mUi->metricComboBox->addItem(availableUnit.first, QVariant::fromValue(availableUnit.second)); } + auto lambdaOnUnitChanged = [this](const QSharedPointer &unit) { + mUi->gridParametersBox->onSizeUnitChanged(unit); + mUi->gridSizeWidget->onSizeUnitChanged(unit); + mUi->horizontalRuler->onSizeUnitChanged(unit); + mUi->verticalRuler->onSizeUnitChanged(unit); + updateRobotInfoWidget(unit); + }; + + connect(mUi->metricComboBox,QOverload::of(&QComboBox::currentIndexChanged), + this, [this, lambdaOnUnitChanged](int index) { + const auto unitValue = mUi->metricComboBox->itemData(index).value(); + auto sizeUnit = mModel.settings().sizeUnit(); + sizeUnit->setSizeUnit(unitValue); + lambdaOnUnitChanged(sizeUnit); + Q_EMIT mUi->gridParametersBox->parametersChanged(); + }); + setSelectedValue(mUi->metricComboBox, sizeUnit->defaultUnit()); } @@ -1210,12 +1223,6 @@ void TwoDModelWidget::onRobotListChange(RobotItem *robotItem) } } -namespace { - bool isTrikModel(const QString &name) { - return name.contains("TrikV62"); - } -} - void TwoDModelWidget::setSelectedRobotItem(RobotItem *robotItem) { mSelectedRobotItem = robotItem; @@ -1226,16 +1233,6 @@ void TwoDModelWidget::setSelectedRobotItem(RobotItem *robotItem) setPortsGroupBoxAndWheelComboBoxes(); updateWheelComboBoxes(); - if (isTrikModel(mSelectedRobotItem->robotModel().info().name())) { - mUi->detailsTab->setMetricSettings(mUi->metricFrame); - connectMetricComboBoxes(); - mUi->pixelsInCmDoubleSpinBox->setValue( - mModel.settings().pixelsInCm()); - } else { - mUi->detailsTab->setMetricSectionsVisible(false); - mUi->metricFrame->hide(); - } - mUi->detailsTab->setDisplay(nullptr); mDisplay = mSelectedRobotItem->robotModel().info().displayWidget(); mDisplay->setParent(this); diff --git a/plugins/robots/common/twoDModel/src/engine/view/twoDModelWidget.ui b/plugins/robots/common/twoDModel/src/engine/view/twoDModelWidget.ui index 25e178b5f4..3082e0cb8e 100644 --- a/plugins/robots/common/twoDModel/src/engine/view/twoDModelWidget.ui +++ b/plugins/robots/common/twoDModel/src/engine/view/twoDModelWidget.ui @@ -7,7 +7,7 @@ 0 0 988 - 669 + 687 @@ -434,36 +434,14 @@ - - - - 0 - 0 - - + - Pixels in cm: + Grid size: - - - true - - - true - - - 4 - - - 1000.000000000000000 - - - 1.000000000000000 - - + @@ -1006,6 +984,12 @@ QDoubleSpinBox
src/engine/view/parts/robotInfoSpinBox.h
+ + twoDModel::view::GridSizeWidget + QWidget +
src/engine/view/parts/gridSizeWidget.h
+ 1 +
diff --git a/plugins/robots/common/twoDModel/twoDModel.pri b/plugins/robots/common/twoDModel/twoDModel.pri index 0f7c0b7418..2b578bbf1e 100644 --- a/plugins/robots/common/twoDModel/twoDModel.pri +++ b/plugins/robots/common/twoDModel/twoDModel.pri @@ -90,6 +90,7 @@ HEADERS += \ $$PWD/src/engine/templates/details/templatesParser.h \ $$PWD/src/engine/templates/details/template.h \ $$PWD/src/engine/templates/templateParserApi.h \ + $$PWD/src/engine/view/parts/gridSizeWidget.h \ $$PWD/src/engine/constraints/constraintsChecker.h \ $$PWD/src/engine/constraints/details/defines.h \ $$PWD/src/engine/constraints/details/constraintsParser.h \ @@ -165,6 +166,7 @@ SOURCES += \ $$PWD/src/engine/view/parts/robotItemPopup.cpp \ $$PWD/src/engine/view/parts/speedPopup.cpp \ $$PWD/src/engine/view/parts/ruler.cpp \ + $$PWD/src/engine/view/parts/gridSizeWidget.cpp \ $$PWD/src/engine/model/model.cpp \ $$PWD/src/engine/model/metricSystem.cpp \ $$PWD/src/engine/model/metricCoordinateSystem.cpp \ diff --git a/plugins/robots/interpreters/interpreterCore/interpreterCoreDefaultSettings.ini b/plugins/robots/interpreters/interpreterCore/interpreterCoreDefaultSettings.ini index bbf3e4c072..35ab47d1d5 100644 --- a/plugins/robots/interpreters/interpreterCore/interpreterCoreDefaultSettings.ini +++ b/plugins/robots/interpreters/interpreterCore/interpreterCoreDefaultSettings.ini @@ -9,7 +9,8 @@ SelectedRobotKit=trikV62Kit 2dFollowingRobot=true 2dCursorType=1 2dShowGrid=true -2dGridCellSize=50 +2dDoubleGridCellSize=50 +2dDefaultGridCellSize=50 2dEditorModeEnable=false approximationLevel=12 diff --git a/qrtranslations/es/plugins/robots/common/twoDModel_es.ts b/qrtranslations/es/plugins/robots/common/twoDModel_es.ts index 8cb1a541d5..4ea4f572db 100644 --- a/qrtranslations/es/plugins/robots/common/twoDModel_es.ts +++ b/qrtranslations/es/plugins/robots/common/twoDModel_es.ts @@ -210,8 +210,48 @@ El objeto "%1" no tiene la propiedad "%2" - - Recursive template expansion detected: %1 -> %2 + + cm + cm + + + + mm + mm + + + + m + m + + + + px + px + + + + Pixels + Píxeles + + + + Centimeters + Centímetros + + + + Meters + Metros + + + + Millimeters + Milímetros + + + + The &lt;template&gt; tag was provided, but the required "name" attribute was missing. @@ -220,18 +260,18 @@ - - The &lt;use&gt; tag must contain a "template" attribute + + the &lt;templates&gt; tag can only contain the &lt;template&gt; tag as a child tag, actual %1 - - The &lt;template&gt; tag was provided, but the required "name" attribute was missing. + + The &lt;use&gt; tag must contain a "template" attribute - - the &lt;templates&gt; tag can only contain the &lt;template&gt; tag as a child tag, actual %1 + + Recursive template expansion detected: %1 -> %2 @@ -354,85 +394,89 @@ Unidades del sistema métrico: - Pixels in cm: - Píxeles por cm: + Píxeles por cm: + + + + Grid size: + Tamaño de cuadrícula: - + Realistic physics Física realista - + Realistic sensors Sensores realistas - + Realistic engines Motores realistas - + Robot height: Altura del robot: - + Robot mass: Masa del robot: - + Wheel diameter: Diámetro de la rueda: - + Robot track: Separación entre ruedas: - + Robot width: Ancho del robot: - - - - + + + + cm cm - + kg kg - + Decrease speed Disminuir velocidad - + Time in 2D model Tiempo en el modelo 2D - + sec. seg. - + Increase speed Aumentar velocidad - + px px @@ -577,44 +621,36 @@ twoDModel::model::SizeUnit - cm - cm + cm - mm - mm + mm - m - m + m - px - px + px - Pixels - Píxeles + Píxeles - Centimeters - Centímetros + Centímetros - Meters - Metros + Metros - Millimeters - Milímetros + Milímetros @@ -825,7 +861,7 @@ twoDModel::view::GridParameters - + Grid Cuadrícula @@ -953,75 +989,74 @@ twoDModel::view::TwoDModelWidget - cm - cm + cm - + kg kg - + Warning Advertencia - + Do you really want to clear scene? ¿Realmente desea limpiar la escena? - + Training mode: solution will not be checked Modo entrenamiento: la solución no será verificada - + Checking mode: solution will be checked, errors will be reported Modo verificación: la solución será comprobada, se informará de errores - + Saving world and robot model Guardando modelo del mundo y del robot - - - + + + 2D model saves (*.xml) Guardados del modelo 2D (*.xml) - + Loading world and robot model Cargando modelo del mundo y del robot - + Loading world without robot model Cargando modelo del mundo sin modelo de robot - + Hide details Ocultar detalles - + Show details Mostrar detalles - - + + No wheel Ausente - + %1 (port %2) %1 (puerto %2) diff --git a/qrtranslations/es/qrutils_es.ts b/qrtranslations/es/qrutils_es.ts index 3daa694b0f..00b63087e8 100644 --- a/qrtranslations/es/qrutils_es.ts +++ b/qrtranslations/es/qrutils_es.ts @@ -69,7 +69,7 @@ División entera por cero - + Remove Eliminar diff --git a/qrtranslations/fr/plugins/robots/common/twoDModel_fr.ts b/qrtranslations/fr/plugins/robots/common/twoDModel_fr.ts index 3f5e5d33bf..2918ca8020 100644 --- a/qrtranslations/fr/plugins/robots/common/twoDModel_fr.ts +++ b/qrtranslations/fr/plugins/robots/common/twoDModel_fr.ts @@ -210,32 +210,72 @@ Annuler - - Recursive template expansion detected: %1 -> %2 + + cm + cm + + + + mm + mm + + + + m + m + + + + px + px + + + + Pixels + Pixels + + + + Centimeters + Centimètres + + + + Meters + Mètres + + + + Millimeters + Millimètres + + + + The &lt;template&gt; tag was provided, but the required "name" attribute was missing. - + Redefinition a template %1 that already exists - - The &lt;use&gt; tag must contain a "template" attribute + + the &lt;templates&gt; tag can only contain the &lt;template&gt; tag as a child tag, actual %1 - - The &lt;template&gt; tag was provided, but the required "name" attribute was missing. + + The &lt;use&gt; tag must contain a "template" attribute - - the &lt;templates&gt; tag can only contain the &lt;template&gt; tag as a child tag, actual %1 + + Recursive template expansion detected: %1 -> %2 - + The &lt;use&gt; tag contains a template=%1 attribute that is not the name of a declared template @@ -347,7 +387,12 @@ Arrêter le programme - + + Grid size: + Taille de la grille: + + + @@ -385,7 +430,7 @@ px - + Left wheel: Roue gauche : @@ -400,12 +445,11 @@ Unités du système métrique : - Pixels in cm: - Nombre de pixels par cm : + Nombre de pixels par cm : - + Realistic physics Physique réaliste @@ -585,44 +629,36 @@ twoDModel::model::SizeUnit - cm - cm + cm - mm - mm + mm - m - m + m - px - px + px - Pixels - Pixels + Pixels - Centimeters - Centimètres + Centimètres - Meters - Mètres + Mètres - Millimeters - Millimètres + Millimètres @@ -833,7 +869,7 @@ twoDModel::view::GridParameters - + Grid Grille @@ -961,7 +997,7 @@ twoDModel::view::TwoDModelWidget - + Warning Attention @@ -979,17 +1015,16 @@ Annuler - cm - cm + cm - + kg kg - + Training mode: solution will not be checked Mode entraînement : la solution ne sera pas vérifiée @@ -1021,7 +1056,7 @@ Chargement du monde sans modèle de robot - + Hide details Masquer les détails @@ -1031,7 +1066,7 @@ Afficher les détails - + No wheel Pas de roue diff --git a/qrtranslations/fr/qrutils_fr.ts b/qrtranslations/fr/qrutils_fr.ts index b4cb02d830..05868bb717 100644 --- a/qrtranslations/fr/qrutils_fr.ts +++ b/qrtranslations/fr/qrutils_fr.ts @@ -88,7 +88,7 @@ Division entière par zéro - + Remove Supprimer diff --git a/qrtranslations/ru/plugins/robots/common/twoDModel_ru.ts b/qrtranslations/ru/plugins/robots/common/twoDModel_ru.ts index 9d88cbc08b..c1bee26909 100644 --- a/qrtranslations/ru/plugins/robots/common/twoDModel_ru.ts +++ b/qrtranslations/ru/plugins/robots/common/twoDModel_ru.ts @@ -416,115 +416,155 @@ Отмена - - Recursive template expansion detected: %1 -> %2 - Обнаружено рекурсивное раскрытие шаблонов: %1 -> %2 + + cm + см - - Redefinition a template %1 that already exists - Переопределение шаблона %1, который уже существует + + mm + мм - - The &lt;use&gt; tag must contain a "template" attribute - &lt;use&gt; тег должен содержать атрибут "template" + + m + м - + + px + пикс + + + + Pixels + Пиксели + + + + Centimeters + Сантиметры + + + + Meters + Метры + + + + Millimeters + Миллиметры + + + The &lt;template&gt; tag was provided, but the required "name" attribute was missing. - &lt;template&gt; тег был предоставлен, но не был предоставлен требуемый атрибут "name" + - + + Redefinition a template %1 that already exists + + + + the &lt;templates&gt; tag can only contain the &lt;template&gt; tag as a child tag, actual %1 - &lt;templates&gt; тег может содержать только &lt;template&gt; как дочерний тег, текущий %1 + + + + + The &lt;use&gt; tag must contain a "template" attribute + - + + Recursive template expansion detected: %1 -> %2 + + + + The &lt;use&gt; tag contains a template=%1 attribute that is not the name of a declared template - &lt;use&gt; тег содержит template=%1 атрибут, который не является именем объявленного шаблона + After substituting the parameters for the template %1, it did not become a valid xml node - После подстановки параметров для шаблона %1, он не стал валидным xml узлом + line %1 - строка %1 + template %1 - шаблон %1 + relative the beginning of the &lt;constraints&gt; tag - относительно начала тега &lt;constraints&gt; + relative to the beginning of the %1 template body - относительно начала тела шаблона %1 + Substitution chain: %1. - Последовательность подстановки шаблонов: %1. + Currently, this method of setting &lt;content&gt; tag for the template %1 is not supported. - На данный момент подобный метод установки тега &lt;content&gt; для шаблона %1 не поддерживается. + When defining the template %1, the syntax %2 was used to substitute an offset %3 for an undeclared parameter %4. - При определении шаблона %1, был использован специальный синтаксис %2 для подстановки параметра по смещению %3, для необъявленного параметра %4. + the &lt;params&gt; tag can only contain the &lt;param&gt; tag as a child tag for template %1, actual tag is &lt;%2&gt; - the &lt;params&gt; тег может содержать только &lt;param&gt; как дочерний тег для шаблона %1, текущий тег &lt;%2&gt; + The &lt;param&gt; tag of template %1 was provided, but the required "name" attribute was missing. - &lt;param&gt; тег шаблона %1 был предоставлен, но требуемый атрибут "name" не был указан. + The &lt;template&gt; of template %1 tag was provided, but the required child tag &lt;content&gt; was missing - &lt;template&gt; тег шаблона %1 был предоставлен, но требуемый дочерний тег &lt;content&gt; не был указан + The using an undeclared parameter %1 for template %2 - Использование необъявленного параметра %1 для шаблона %2 + The &lt;use&gt; tag can only contain a child tag &lt;with&gt; - &lt;use&gt; тег может содержать только &lt;with&gt; как дочерний тег + The parameter %1 of template %2 has no default value and was not explicitly specified by the user - Параметр %1 шаблона %2 не имеет значения по умолчанию и не был выставлен явно + Error while template substitution: %1 - Ошибка при раскрытии шаблона: %1 + Ошибка при раскрытии шаблона: %1 Error while parsing template: %1 - Ошибка при разборе шаблона: %1 + Ошибка при разборе шаблона: %1 @@ -557,7 +597,12 @@ Остановить программу - + + Grid size: + Шаг сетки: + + + @@ -595,7 +640,7 @@ пикс - + Left wheel: Левое колесо: @@ -610,12 +655,11 @@ Единицы измерения - Pixels in cm: - Кол-во пикселей в см + Кол-во пикселей в см - + Realistic physics Реалистичная физика @@ -869,44 +913,36 @@ twoDModel::model::SizeUnit - cm - см + см - mm - мм + мм - m - м + м - px - пикс + пикс - Pixels - Пиксели + Пиксели - Centimeters - Сантиметры + Сантиметры - Meters - Метры + Метры - Millimeters - Миллиметры + Миллиметры @@ -1180,7 +1216,7 @@ twoDModel::view::GridParameters - + Grid Сетка @@ -1312,7 +1348,7 @@ twoDModel::view::TwoDModelWidget - + Warning Предупреждение @@ -1330,17 +1366,16 @@ Отмена - cm - см + см - + kg кг - + Training mode: solution will not be checked Режим тренировки: решение не будет проверяться @@ -1388,7 +1423,7 @@ Попытка загрузить слишком большое изображение может заморозить выполнение на некоторое время. Продолжить? - + Hide details Скрыть детали @@ -1398,7 +1433,7 @@ Показать детали - + No wheel Отсутствует diff --git a/qrtranslations/ru/qrutils_ru.ts b/qrtranslations/ru/qrutils_ru.ts index 737f9791d3..d274519293 100644 --- a/qrtranslations/ru/qrutils_ru.ts +++ b/qrtranslations/ru/qrutils_ru.ts @@ -92,7 +92,7 @@ Целичисленное деление на ноль - + Remove Удалить diff --git a/qrtranslations/vi/plugins/robots/common/twoDModel_vi.ts b/qrtranslations/vi/plugins/robots/common/twoDModel_vi.ts index 5168d8300e..c3adc7c9ff 100644 --- a/qrtranslations/vi/plugins/robots/common/twoDModel_vi.ts +++ b/qrtranslations/vi/plugins/robots/common/twoDModel_vi.ts @@ -210,8 +210,48 @@ Đối tượng "%1" không có thuộc tính "%2" - - Recursive template expansion detected: %1 -> %2 + + cm + cm + + + + mm + mm + + + + m + m + + + + px + px + + + + Pixels + Điểm ảnh + + + + Centimeters + Xentimét + + + + Meters + Mét + + + + Millimeters + Milimét + + + + The &lt;template&gt; tag was provided, but the required "name" attribute was missing. @@ -220,18 +260,18 @@ - - The &lt;use&gt; tag must contain a "template" attribute + + the &lt;templates&gt; tag can only contain the &lt;template&gt; tag as a child tag, actual %1 - - The &lt;template&gt; tag was provided, but the required "name" attribute was missing. + + The &lt;use&gt; tag must contain a "template" attribute - - the &lt;templates&gt; tag can only contain the &lt;template&gt; tag as a child tag, actual %1 + + Recursive template expansion detected: %1 -> %2 @@ -354,85 +394,89 @@ Đơn vị hệ mét: - Pixels in cm: - Số pixel trên 1 cm: + Số pixel trên 1 cm: + + + + Grid size: + Kích thước lưới: - + Realistic physics Vật lý thực tế - + Realistic sensors Cảm biến thực tế - + Realistic engines Động cơ thực tế - + Robot height: Chiều cao robot: - + Robot mass: Khối lượng robot: - + Wheel diameter: Đường kính bánh xe: - + Robot track: Chiều rộng cơ sở robot: - + Robot width: Chiều rộng robot: - - - - + + + + cm cm - + kg kg - + Decrease speed Giảm tốc độ - + Time in 2D model Thời gian trong mô hình 2D - + sec. giây. - + Increase speed Tăng tốc độ - + px px @@ -577,44 +621,36 @@ twoDModel::model::SizeUnit - cm - cm + cm - mm - mm + mm - m - m + m - px - px + px - Pixels - Điểm ảnh + Điểm ảnh - Centimeters - Xentimét + Xentimét - Meters - Mét + Mét - Millimeters - Milimét + Milimét @@ -825,7 +861,7 @@ twoDModel::view::GridParameters - + Grid Lưới @@ -953,75 +989,74 @@ twoDModel::view::TwoDModelWidget - cm - cm + cm - + kg kg - + Warning Cảnh báo - + Do you really want to clear scene? Bạn có thực sự muốn xóa toàn bộ cảnh? - + Training mode: solution will not be checked Chế độ luyện tập: lời giải sẽ không được kiểm tra - + Checking mode: solution will be checked, errors will be reported Chế độ kiểm tra: lời giải sẽ được kiểm tra, các lỗi sẽ được báo cáo - + Saving world and robot model Đang lưu mô hình thế giới và robot - - - + + + 2D model saves (*.xml) Tệp lưu mô hình 2D (*.xml) - + Loading world and robot model Đang tải mô hình thế giới và robot - + Loading world without robot model Đang tải mô hình thế giới mà không có mô hình robot - + Hide details Ẩn chi tiết - + Show details Hiển thị chi tiết - - + + No wheel Không có bánh xe - + %1 (port %2) %1 (cổng %2) diff --git a/qrtranslations/vi/qrutils_vi.ts b/qrtranslations/vi/qrutils_vi.ts index 7cd8765ed6..021d520e96 100644 --- a/qrtranslations/vi/qrutils_vi.ts +++ b/qrtranslations/vi/qrutils_vi.ts @@ -69,7 +69,7 @@ Chia số nguyên cho 0 - + Remove Xóa diff --git a/qrutils/graphicsUtils/abstractItem.cpp b/qrutils/graphicsUtils/abstractItem.cpp index e627e83efb..a101a0f53f 100644 --- a/qrutils/graphicsUtils/abstractItem.cpp +++ b/qrutils/graphicsUtils/abstractItem.cpp @@ -14,6 +14,7 @@ #include "abstractItem.h" +#include #include #include #include @@ -686,16 +687,7 @@ void AbstractItem::copyTo(AbstractItem * const other) const , QOverload::of(&AbstractItem::setBrush)); } -qreal AbstractItem::alignedCoordinate(qreal coord, const int indexGrid) const +qreal AbstractItem::alignedCoordinate(qreal coord, const qreal gridSize) const { - const int coef = static_cast(coord) / indexGrid; - const int coefSign = coef ? coef / qAbs(coef) : 0; - - if (qAbs(qAbs(coord) - qAbs(coef) * indexGrid) <= indexGrid / 2.0) { - return coef * indexGrid; - } else if (qAbs(qAbs(coord) - (qAbs(coef) + 1) * indexGrid) <= indexGrid / 2.0) { - return (coef + coefSign) * indexGrid; - } - - return coord; + return std::round(coord / gridSize) * gridSize; } diff --git a/qrutils/graphicsUtils/abstractItem.h b/qrutils/graphicsUtils/abstractItem.h index 78bcad5af7..1a991df017 100644 --- a/qrutils/graphicsUtils/abstractItem.h +++ b/qrutils/graphicsUtils/abstractItem.h @@ -192,7 +192,7 @@ class QRUTILS_EXPORT AbstractItem : public QGraphicsObject virtual void updateCursor(QGraphicsSceneHoverEvent *event); void copyTo(AbstractItem * const other) const; - qreal alignedCoordinate(qreal coord, const int indexGrid) const; + qreal alignedCoordinate(qreal coord, const qreal gridSize) const; void setXYWithDragState(const QPointF pos); private: diff --git a/qrutils/graphicsUtils/gridDrawer.cpp b/qrutils/graphicsUtils/gridDrawer.cpp index 2c86fab201..d6e0d64ed5 100644 --- a/qrutils/graphicsUtils/gridDrawer.cpp +++ b/qrutils/graphicsUtils/gridDrawer.cpp @@ -13,30 +13,30 @@ * limitations under the License. */ #include - +#include #include "gridDrawer.h" using namespace graphicsUtils; -GridDrawer::GridDrawer() -{ -} +GridDrawer::GridDrawer() = default; -void GridDrawer::drawGrid(QPainter *painter, const QRectF &rect, const int indexGrid) +void GridDrawer::drawGrid(QPainter *painter, const QRectF &rect, const qreal gridSize) { - const int left = static_cast(rect.left()); - const int right = static_cast(rect.right()); - const int top = static_cast(rect.top()); - const int bottom = static_cast(rect.bottom()); + const auto firstVerticalLineIndex = static_cast(std::floor(rect.left() / gridSize)); + const auto lastVerticalLineIndex = static_cast(std::ceil(rect.right() / gridSize)); - const int startX = left / indexGrid * indexGrid; - const int startY = top / indexGrid * indexGrid; - - for (int i = startX; i <= right; i += indexGrid) { - painter->drawLine(i, top, i, bottom); + for (auto i = firstVerticalLineIndex; i <= lastVerticalLineIndex; ++i) { + const auto currentVerticalLineX = i * gridSize; + painter->drawLine(QPointF(currentVerticalLineX, rect.top()), + QPointF(currentVerticalLineX, rect.bottom())); } - for (int i = startY; i <= bottom; i += indexGrid) { - painter->drawLine(left, i, right, i); + const auto firstHorizontalLineIndex = static_cast(std::floor(rect.top() / gridSize)); + const auto lastHorizontalLineIndex = static_cast(std::floor(rect.bottom() / gridSize)); + + for (auto i = firstHorizontalLineIndex; i <= lastHorizontalLineIndex; ++i) { + const auto currentHorizontalLineY = i * gridSize; + painter->drawLine(QPointF(rect.left(), currentHorizontalLineY), + QPointF(rect.right(), currentHorizontalLineY)); } } diff --git a/qrutils/graphicsUtils/gridDrawer.h b/qrutils/graphicsUtils/gridDrawer.h index 543102636e..63b1d641c4 100644 --- a/qrutils/graphicsUtils/gridDrawer.h +++ b/qrutils/graphicsUtils/gridDrawer.h @@ -24,7 +24,7 @@ class QRUTILS_EXPORT GridDrawer { public: GridDrawer(); - void drawGrid(QPainter *painter, const QRectF &rect, const int indexGrid); + void drawGrid(QPainter *painter, const QRectF &rect, const qreal indexGrid); }; }