#include "lts_angle_edit.h" #include "ui_lts_angle_edit.h" #include namespace LtsWidgets { inline constexpr double pi() { return M_PI; } inline constexpr double deg2rad() { return pi() / 180.; } inline constexpr double rad2deg() { return 1. / deg2rad(); } constexpr int maxAngleDeg = 360; constexpr int maxAngleMil = 6400; constexpr std::tuple c_limDeg (0, maxAngleDeg,0, 10); constexpr std::tuple c_limMil(0, maxAngleMil,0, 50); constexpr std::tuple c_limRad(-99999, 99999, 3, 1); inline constexpr double mil2Deg(const double &mil) { return maxAngleDeg * mil / maxAngleMil; } inline constexpr double deg2Mil(const double &angleDeg) { return maxAngleMil * angleDeg / maxAngleDeg; } inline constexpr double deg2Rad(const double &angleDeg) { return angleDeg * deg2rad(); } inline constexpr double rad2Degree(const double &angleRad) { return angleRad * 180/pi(); } inline constexpr double mil2Rad(const double &mil) { return deg2Rad(mil2Deg(mil)); } inline constexpr double rad2Mil(const double &angleRad) { return deg2Mil(rad2Degree(angleRad)); } LtsAngleEdit::LtsAngleEdit(QWidget *parent) : QWidget(parent), m_ui(new Ui_LtsAngleEdit) { m_ui->setupUi(this); } LtsAngleEdit::~LtsAngleEdit() { delete m_ui; } void LtsAngleEdit::initAngleEditWidget(const unsigned int sboxCount) { m_dboxLimitMap.insert(AngleUnitType::Deg, c_limDeg); m_dboxLimitMap.insert(AngleUnitType::Mil, c_limMil); m_dboxLimitMap.insert(AngleUnitType::Rad, c_limRad); m_hiddenUnits.clear(); m_hiddenUnits.insert((int)AngleUnitType::Rad); for(unsigned int i=0; i spinbox = QSharedPointer(new QDoubleSpinBox(this) ); spinbox->setValue(0); spinbox->setAlignment(Qt::AlignRight); spinbox->setMinimumWidth(91); spinbox.data()->setObjectName(spinBoxName+QString::number(m_sBoxMap.count())); m_ui->hLayoutSpinbox->addWidget(spinbox.data(), 0); m_sBoxMap.insert(m_sBoxMap.count(), spinbox); } m_ui->hLayoutSpinbox->setContentsMargins(1,1,1,1); connect(m_ui->cBoxAngleUnit, qOverload(&QComboBox::currentIndexChanged), this, &LtsAngleEdit::onCBoxAngleUnitChanged); setCboxUnit(); } void LtsAngleEdit::setValue(const double value, unsigned int dboxIndex) { if ((int)dboxIndex > m_sBoxMap.count()) return; auto spinbox = m_sBoxMap.value(dboxIndex); spinbox->setValue(value); } void LtsAngleEdit::setValue(const double value, AngleUnitType valueUnit, unsigned int dboxIndex) { setValue(getAngleConverted(value, getAngleCurrentUnit(), valueUnit),dboxIndex); } void LtsAngleEdit::hideUnits(const QVector &list) { for(auto u : list) m_hiddenUnits.insert((int)u); setCboxUnit(); } void LtsAngleEdit::showUnits(const QVector &list) { for (const auto &u : list) m_hiddenUnits.remove((int)u); setCboxUnit(); } void LtsAngleEdit::setCboxUnit() { m_ui->cBoxAngleUnit->clear(); const std::vector allUnits = {AngleUnitType::Deg, AngleUnitType::Mil, AngleUnitType::Rad}; for(const auto &u : allUnits) { if (m_hiddenUnits.contains((int)u)) continue; m_ui->cBoxAngleUnit->insertItem(static_cast(u), toString(u),static_cast(u)); } setAngleUnit(AngleUnitType::Deg); } void LtsAngleEdit::setValue(const double value, AngleUnitType valueUnit) { setValue(getAngleConverted(value, getAngleCurrentUnit(), valueUnit),0); } void LtsAngleEdit::setAngleUnit(const AngleUnitType &type) { m_ui->cBoxAngleUnit->setCurrentIndex(static_cast(type)); } LtsAngleEdit::AngleUnitType LtsAngleEdit::getAngleCurrentUnit() const { return static_cast(m_ui->cBoxAngleUnit->currentIndex()); } double LtsAngleEdit::getAngle(unsigned int sboxIndex) const { if ((int)sboxIndex > m_sBoxMap.count()) return 0; auto spinbox = m_sBoxMap.value(sboxIndex); return spinbox->value(); } QString LtsAngleEdit::toString(LtsAngleEdit::AngleUnitType t) { switch(t) { case AngleUnitType::Deg: return tr("Degree"); case AngleUnitType::Mil: return tr("Mil"); case AngleUnitType::Rad: return tr("Radian"); default: return tr(""); } return tr(""); } void LtsAngleEdit::onCBoxAngleUnitChanged() { AngleUnitType newUnit = static_cast(m_ui->cBoxAngleUnit->currentData().toInt()); for(auto dbox : qAsConst(m_sBoxMap)) { const double value = getAngleConverted(dbox->value(), newUnit, m_currAngleUnit); auto mapVal = m_dboxLimitMap.value(newUnit); dbox->setMinimum(std::get(mapVal)); dbox->setMaximum(std::get(mapVal)); dbox->setDecimals(std::get(mapVal)); dbox->setSingleStep(std::get(mapVal)); dbox->setValue(value); } m_currAngleUnit = newUnit; } double LtsAngleEdit::getAngleConverted(const double angle, LtsAngleEdit::AngleUnitType newAngleUnit, LtsAngleEdit::AngleUnitType oldAngleUnit) { double convertedAngle = angle; if (oldAngleUnit == AngleUnitType::Deg && newAngleUnit == AngleUnitType::Mil ) convertedAngle = deg2Mil(angle); else if (oldAngleUnit == AngleUnitType::Deg && newAngleUnit == AngleUnitType::Rad ) convertedAngle = deg2Rad(angle); else if (oldAngleUnit == AngleUnitType::Mil && newAngleUnit == AngleUnitType::Deg ) convertedAngle = mil2Deg(angle); else if (oldAngleUnit == AngleUnitType::Mil && newAngleUnit == AngleUnitType::Rad ) convertedAngle = mil2Rad(angle); else if (oldAngleUnit == AngleUnitType::Rad && newAngleUnit == AngleUnitType::Deg ) convertedAngle = rad2Degree(angle); else if (oldAngleUnit == AngleUnitType::Rad && newAngleUnit == AngleUnitType::Mil ) convertedAngle = rad2Mil(angle); return convertedAngle; } void LtsAngleEdit::setEnable(int sbIndex, bool enabled) { if ((int)sbIndex > m_sBoxMap.count()) return; m_sBoxMap.value(sbIndex)->setEnabled(enabled); } void LtsAngleEdit::showSpinbox(int sbIndex, bool visible) { if ((int)sbIndex > m_sBoxMap.count()) return; m_sBoxMap.value(sbIndex)->setVisible(visible); } }