diff --git a/libs/piqt_widgets/pivaluetree_edit_parameters.cpp b/libs/piqt_widgets/pivaluetree_edit_parameters.cpp index 09dab33..4efa616 100644 --- a/libs/piqt_widgets/pivaluetree_edit_parameters.cpp +++ b/libs/piqt_widgets/pivaluetree_edit_parameters.cpp @@ -112,6 +112,7 @@ void PIValueTreeEditParameters::createAttributes(QList & list, auto dit = dal.makeIterator(); while (dit.next()) { auto * ve = new PIVariantEdit(); + ve->setAttributes(PIVariantEditorBase::editorDefaultAttributes(dit.value().typeID())); ve->setValue(dit.value()); ve->setProperty(property_name, PI2QString(dit.key())); list << ve; diff --git a/libs/piqt_widgets/pivariant_edit_widgets.cpp b/libs/piqt_widgets/pivariant_edit_widgets.cpp index 3de5aba..0b669b0 100644 --- a/libs/piqt_widgets/pivariant_edit_widgets.cpp +++ b/libs/piqt_widgets/pivariant_edit_widgets.cpp @@ -1,8 +1,11 @@ #include "pivariant_edit_widgets.h" +#include "evalspinbox.h" #include "pivaluetree.h" #include "pivariant_edit_enum.h" #include "pivarianttypes.h" +#include "scroll_spin_box.h" +#include "spinslider.h" #include #include @@ -29,88 +32,231 @@ REGISTER_PIVARIANTEDITOR(PIVariantTypes::Dir, PIVariantEditors::Dir); using Attribute = PIValueTree::Attribute; -// PIVariantEditors::Int -PIVariantMap PIVariantEditors::Int::attributes() const { - return { - {Attribute::minimum, widget->minimum() }, - {Attribute::maximum, widget->maximum() }, - {Attribute::singleStep, widget->singleStep()}, - {Attribute::prefix, prefix }, - {Attribute::suffix, suffix }, - }; +// PIVariantEditors::NumberBase + +PIVariantEditors::NumberBase::NumberBase() {} + + +void PIVariantEditors::NumberBase::setValueNumeric(double v) { + switch (type) { + case tSpinBox: { + auto * w = qobject_cast(widget); + if (w) w->setValue(v); + } break; + case tSlider: { + auto * w = qobject_cast(widget); + if (w) w->setValue(v); + } break; + case tSpinSlider: { + auto * w = qobject_cast(widget); + if (w) w->setValue(v); + } break; + case tEvalSpinBox: { + auto * w = qobject_cast(widget); + if (w) { + PIString vs = PIString::fromNumber(v), es = PIString::fromNumber(w->value()); + if (vs != es) w->setValue(v); + } + } break; + case tScrollSpinBox: { + auto * w = qobject_cast(widget); + if (w) w->setValue(v); + } break; + default: break; + } } -PIVariantMap PIVariantEditors::Int::defaultAttributes() { +double PIVariantEditors::NumberBase::valueNumeric() const { + switch (type) { + case tSpinBox: { + auto * w = qobject_cast(widget); + if (w) return w->value(); + } break; + case tSlider: { + auto * w = qobject_cast(widget); + if (w) return w->value(); + } break; + case tSpinSlider: { + auto * w = qobject_cast(widget); + if (w) return w->value(); + } break; + case tEvalSpinBox: { + auto * w = qobject_cast(widget); + if (w) return w->value(); + } break; + case tScrollSpinBox: { + auto * w = qobject_cast(widget); + if (w) return w->value(); + } break; + default: break; + } + return 0.; +} + + +PIVariantMap PIVariantEditors::NumberBase::attributes() const { + auto etype = createTypes(); + etype.selectValue(type); + PIVariantMap ret = { + {Attribute::widgetType, etype }, + {Attribute::prefix, prefix}, + {Attribute::suffix, suffix}, + }; + switch (type) { + case tSpinBox: { + auto * w = qobject_cast(widget); + if (w) { + ret[Attribute::minimum] = w->minimum(); + ret[Attribute::maximum] = w->maximum(); + ret[Attribute::singleStep] = w->singleStep(); + if (!is_int) ret[Attribute::decimals] = w->decimals(); + } + } break; + case tSlider: { + auto * w = qobject_cast(widget); + if (w) { + ret[Attribute::minimum] = w->minimum(); + ret[Attribute::maximum] = w->maximum(); + ret[Attribute::singleStep] = w->singleStep(); + } + } break; + case tSpinSlider: { + auto * w = qobject_cast(widget); + if (w) { + ret[Attribute::minimum] = w->minimum(); + ret[Attribute::maximum] = w->maximum(); + ret[Attribute::singleStep] = w->singleStep(); + if (!is_int) ret[Attribute::decimals] = w->decimals(); + } + } break; + case tEvalSpinBox: { + auto * w = qobject_cast(widget); + if (w) { + ret[Attribute::expression] = Q2PIString(w->expression()); + } + } break; + default: break; + } + return ret; +} + + +PIVariantMap PIVariantEditors::NumberBase::defaultAttributes() { return { + {Attribute::widgetType, createTypes() }, {Attribute::minimum, -std::numeric_limits::max()}, {Attribute::maximum, std::numeric_limits::max() }, {Attribute::singleStep, 1. }, + {Attribute::decimals, 3 }, {Attribute::prefix, "" }, {Attribute::suffix, "" }, }; } -void PIVariantEditors::Int::retranslate() { - widget->setPrefix(PIVariantEditorBase::vtTr(prefix)); - widget->setSuffix(PIVariantEditorBase::vtTr(suffix)); +PIVariantTypes::Enum PIVariantEditors::NumberBase::createTypes() { + PIVariantTypes::Enum ret; + ret << PIVariantTypes::Enumerator(tSpinBox, "spin box") << PIVariantTypes::Enumerator(tSlider, "slider") + << PIVariantTypes::Enumerator(tSpinSlider, "spin-slider") << PIVariantTypes::Enumerator(tEvalSpinBox, "eval spin box") + << PIVariantTypes::Enumerator(tScrollSpinBox, "scroll spin box"); + ret.selectValue(tSpinBox); + return ret; } -void PIVariantEditors::Int::applyAttributes(const PIVariantMap & a) { - prefix = a.value(Attribute::prefix).toString(); - suffix = a.value(Attribute::suffix).toString(); - widget->setRange(a.value(Attribute::minimum, widget->minimum()).toInt(), a.value(Attribute::maximum, widget->maximum()).toInt()); - widget->setSingleStep(a.value(Attribute::singleStep, widget->singleStep()).toInt()); - widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool()); - retranslate(); +void PIVariantEditors::NumberBase::retranslate() { + switch (type) { + case tSpinBox: { + auto * w = qobject_cast(widget); + if (!w) return; + w->setPrefix(PIVariantEditorBase::vtTr(prefix)); + w->setSuffix(PIVariantEditorBase::vtTr(suffix)); + } break; + case tSpinSlider: { + auto * w = qobject_cast(widget); + if (!w) return; + w->setPrefix(PIVariantEditorBase::vtTr(prefix)); + w->setSuffix(PIVariantEditorBase::vtTr(suffix)); + } break; + default: break; + } } +void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) { + Type new_type = static_cast(a.value(Attribute::widgetType).toEnum().selectedValue()); + if (type != new_type) { + type = new_type; + if (widget) delete widget; + widget = nullptr; + // clang-format off + switch (type) { + case tSpinBox : widget = new QDoubleSpinBox(); break; + case tSlider : widget = new QSlider (Qt::Horizontal); break; + case tSpinSlider : widget = new SpinSlider (); break; + case tEvalSpinBox : widget = new EvalSpinBox (); break; + case tScrollSpinBox: widget = new ScrollSpinBox (); break; + default: break; + } + // clang-format on + if (!widget) return; + widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + layout()->addWidget(widget); + } + prefix = a.value(Attribute::prefix).toString(); + suffix = a.value(Attribute::suffix).toString(); + double min = a.value(Attribute::minimum).toDouble(); + double max = a.value(Attribute::maximum).toDouble(); + double step = a.value(Attribute::singleStep).toDouble(); + int dec = is_int ? 0 : a.value(Attribute::decimals).toInt(); + switch (type) { + case tSpinBox: { + auto * w = qobject_cast(widget); + if (!w) return; + w->setPrefix(PIVariantEditorBase::vtTr(prefix)); + w->setSuffix(PIVariantEditorBase::vtTr(suffix)); + w->setRange(min, max); + w->setSingleStep(step); + w->setDecimals(dec); + } break; + case tSlider: { + auto * w = qobject_cast(widget); + if (!w) return; + w->setTickInterval(piRoundd(piMaxd(1., (max - min) / 100.))); + w->setRange(min, max); + w->setSingleStep(step); + } break; + case tSpinSlider: { + auto * w = qobject_cast(widget); + if (!w) return; + w->setPrefix(PIVariantEditorBase::vtTr(prefix)); + w->setSuffix(PIVariantEditorBase::vtTr(suffix)); + w->setMinimum(min); + w->setMaximum(max); + w->setSingleStep(step); + w->setDecimals(dec); + } break; + case tEvalSpinBox: { + auto * w = qobject_cast(widget); + if (!w) return; + w->setExpression(PI2QString(a.value(Attribute::expression).toString())); + } break; + case tScrollSpinBox: { + auto * w = qobject_cast(widget); + if (!w) return; + } break; + default: break; + } +} + + +// PIVariantEditors::Int + + // PIVariantEditors::Double -PIVariantMap PIVariantEditors::Double::attributes() const { - return { - {Attribute::minimum, widget->minimum() }, - {Attribute::maximum, widget->maximum() }, - {Attribute::singleStep, widget->singleStep()}, - {Attribute::decimals, widget->decimals() }, - {Attribute::prefix, prefix }, - {Attribute::suffix, suffix }, - }; -} - - -PIVariantMap PIVariantEditors::Double::defaultAttributes() { - return { - {Attribute::minimum, -std::numeric_limits::max()}, - {Attribute::maximum, std::numeric_limits::max() }, - {Attribute::singleStep, 1. }, - {Attribute::decimals, 3 }, - {Attribute::prefix, "" }, - {Attribute::suffix, "" }, - }; -} - - -void PIVariantEditors::Double::retranslate() { - widget->setPrefix(PIVariantEditorBase::vtTr(prefix)); - widget->setSuffix(PIVariantEditorBase::vtTr(suffix)); -} - - -void PIVariantEditors::Double::applyAttributes(const PIVariantMap & a) { - prefix = a.value(Attribute::prefix).toString(); - suffix = a.value(Attribute::suffix).toString(); - widget->setRange(a.value(Attribute::minimum, widget->minimum()).toDouble(), a.value(Attribute::maximum, widget->maximum()).toDouble()); - widget->setSingleStep(a.value(Attribute::singleStep, widget->singleStep()).toDouble()); - widget->setDecimals(a.value(Attribute::decimals, widget->decimals()).toInt()); - widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool()); - retranslate(); -} - // PIVariantEditors::String diff --git a/libs/piqt_widgets/pivariant_edit_widgets.h b/libs/piqt_widgets/pivariant_edit_widgets.h index 98f24a4..68bded4 100644 --- a/libs/piqt_widgets/pivariant_edit_widgets.h +++ b/libs/piqt_widgets/pivariant_edit_widgets.h @@ -36,6 +36,35 @@ namespace PIVariantEditors { +class QAD_PIQT_UTILS_EXPORT NumberBase: public PIVariantEditorBase { + Q_OBJECT + +public: + NumberBase(); + void setValueNumeric(double v); + double valueNumeric() const; + PIVariantMap attributes() const override; + static PIVariantMap defaultAttributes(); + static PIVariantTypes::Enum createTypes(); + void retranslate() override; + +protected: + void applyAttributes(const PIVariantMap & a) override; + enum Type { + tInvalid, + tSpinBox, + tSlider, + tSpinSlider, + tEvalSpinBox, + tScrollSpinBox, + }; + Type type = tInvalid; + PIString prefix, suffix; + QWidget * widget = nullptr; + bool is_int = false; +}; + + class QAD_PIQT_UTILS_EXPORT Bool: public PIVariantEditorBase { Q_OBJECT @@ -52,47 +81,29 @@ private: }; -class QAD_PIQT_UTILS_EXPORT Int: public PIVariantEditorBase { +class QAD_PIQT_UTILS_EXPORT Int: public NumberBase { Q_OBJECT public: - Int() { - widget = new QSpinBox(); - widget->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); - layout()->addWidget(widget); + Int(): NumberBase() { + is_int = true; + applyAttributes(NumberBase::defaultAttributes()); } - void setValue(const PIVariant & v) override { widget->setValue(v.toInt()); } - PIVariant value() const override { return widget->value(); } - PIVariantMap attributes() const override; - static PIVariantMap defaultAttributes(); - void retranslate(); - -private: - void applyAttributes(const PIVariantMap & a) override; - PIString prefix, suffix; - QSpinBox * widget; + void setValue(const PIVariant & v) override { setValueNumeric(v.toInt()); } + PIVariant value() const override { return piRoundd(valueNumeric()); } }; -class QAD_PIQT_UTILS_EXPORT Double: public PIVariantEditorBase { +class QAD_PIQT_UTILS_EXPORT Double: public NumberBase { Q_OBJECT public: - Double() { - widget = new QDoubleSpinBox(); - widget->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); - layout()->addWidget(widget); + Double(): NumberBase() { + is_int = false; + applyAttributes(NumberBase::defaultAttributes()); } - void setValue(const PIVariant & v) override { widget->setValue(v.toDouble()); } - PIVariant value() const override { return widget->value(); } - PIVariantMap attributes() const override; - static PIVariantMap defaultAttributes(); - void retranslate(); - -private: - void applyAttributes(const PIVariantMap & a) override; - PIString prefix, suffix; - QDoubleSpinBox * widget; + void setValue(const PIVariant & v) override { setValueNumeric(v.toDouble()); } + PIVariant value() const override { return valueNumeric(); } };