Reworked value handling.
This commit is contained in:
@@ -30,29 +30,21 @@ void BCDelightPMWidget::loadWidgetsFromResources()
|
|||||||
|
|
||||||
QString resourcePath = ":/resources/smile";
|
QString resourcePath = ":/resources/smile";
|
||||||
|
|
||||||
// 2. Iterator erstellen
|
|
||||||
// QDir::Files sorgt dafür, dass wir nur echte Dateien finden, keine Ordner wie "." oder ".."
|
|
||||||
// QDirIterator::Subdirectories würde auch in Unterordnern suchen (falls nötig)
|
|
||||||
QDirIterator it(resourcePath, QDir::Files);
|
QDirIterator it(resourcePath, QDir::Files);
|
||||||
|
|
||||||
//QFileInfoList fileList:
|
|
||||||
// 3. Schleife: Solange es noch Einträge gibt
|
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
// Iteriert zum nächsten Eintrag und gibt den kompletten virtuellen Pfad zurück
|
|
||||||
// z.B. ":/icons/ball_red.png"
|
|
||||||
QString fullPath = it.next();
|
QString fullPath = it.next();
|
||||||
// Eine Zufallsfarbe für den Button-Hintergrund generieren
|
// Eine Zufallsfarbe für den Button-Hintergrund generieren
|
||||||
QStringList colors = {"#ff5555", "#50fa7b", "#8be9fd", "#ffb86c"};
|
QStringList colors = {"#ff5555", "#50fa7b", "#8be9fd", "#ffb86c"};
|
||||||
QString randomColor = colors.at(QRandomGenerator::global()->bounded(colors.size()));
|
|
||||||
|
|
||||||
// Ihre Funktion aufrufen und den Pfad übergeben
|
// Ihre Funktion aufrufen und den Pfad übergeben
|
||||||
createFlyingWidget(fullPath, randomColor);
|
createFlyingWidget(fullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BCDelightPMWidget::createFlyingWidget(const QString& iconPath, const QString &color)
|
void BCDelightPMWidget::createFlyingWidget(const QString& iconPath)
|
||||||
{
|
{
|
||||||
// 1. Button als Kind des Playground erstellen
|
// 1. Button als Kind des Playground erstellen
|
||||||
QPushButton *btn = new QPushButton(_playGround);
|
QPushButton *btn = new QPushButton(_playGround);
|
||||||
@@ -86,24 +78,16 @@ void BCDelightPMWidget::createFlyingWidget(const QString& iconPath, const QStrin
|
|||||||
|
|
||||||
btn->show();
|
btn->show();
|
||||||
|
|
||||||
// --- NEU: Opacity Effekt hinzufügen ---
|
|
||||||
// 1. Effekt erstellen. 'btn' wird der Parent und kümmert sich ums Löschen.
|
|
||||||
QGraphicsOpacityEffect *opacityEff = new QGraphicsOpacityEffect(btn);
|
QGraphicsOpacityEffect *opacityEff = new QGraphicsOpacityEffect(btn);
|
||||||
|
|
||||||
// 2. Startwert setzen (1.0 = voll sichtbar)
|
|
||||||
opacityEff->setOpacity(1.0);
|
opacityEff->setOpacity(1.0);
|
||||||
|
|
||||||
// 3. Dem Widget zuweisen. WICHTIG: Das Widget übernimmt den Besitz.
|
|
||||||
btn->setGraphicsEffect(opacityEff);
|
btn->setGraphicsEffect(opacityEff);
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
|
|
||||||
btn->show();
|
btn->show();
|
||||||
// ... (Rest der Funktion: move und append) ...
|
|
||||||
btn->move(50 + _flyingWidgets.size() * 60, 50);
|
btn->move(50 + _flyingWidgets.size() * 60, 50);
|
||||||
_flyingWidgets.append(btn);
|
_flyingWidgets.append(btn);
|
||||||
|
|
||||||
|
|
||||||
// Startzustand: Unsichtbar in der Mitte
|
|
||||||
btn->move(_playGround->width()/2, _playGround->height()/2);
|
btn->move(_playGround->width()/2, _playGround->height()/2);
|
||||||
opacityEff->setOpacity(0.0);
|
opacityEff->setOpacity(0.0);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The BCDelightPMWidget class : Graphische Effekte für unseren Produktmanager Simon.
|
* @brief The BCDelightPMWidget class : Demonstration Graphischer
|
||||||
|
* Effekte für unseren Produktmanager Simon.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class BCDelightPMWidget : public QObject
|
class BCDelightPMWidget : public QObject
|
||||||
@@ -22,10 +23,9 @@ public slots:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
void loadWidgetsFromResources();
|
void loadWidgetsFromResources();
|
||||||
void createFlyingWidget(const QString& iconPath, const QString &color);
|
void createFlyingWidget(const QString& iconPath);
|
||||||
|
|
||||||
QWidget *_playGround{};
|
|
||||||
|
|
||||||
|
QWidget* _playGround{};
|
||||||
// Liste der Widgets, die wir bewegen
|
// Liste der Widgets, die wir bewegen
|
||||||
QList<QWidget*> _flyingWidgets;
|
QList<QWidget*> _flyingWidgets;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ void BCDeviceView::setDeviceID( BCDevice::ID deviceID )
|
|||||||
_devideID = deviceID;
|
_devideID = deviceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
BCDevice::ID BCDeviceView::getDeviceID() const
|
BCDevice::ID BCDeviceView::deviceID() const
|
||||||
{
|
{
|
||||||
return _devideID;
|
return _devideID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
explicit BCDeviceView(QWidget *parent = nullptr);
|
explicit BCDeviceView(QWidget *parent = nullptr);
|
||||||
|
|
||||||
void setDeviceID( BCDevice::ID deviceID );
|
void setDeviceID( BCDevice::ID deviceID );
|
||||||
BCDevice::ID getDeviceID() const;
|
BCDevice::ID deviceID() const;
|
||||||
|
|
||||||
const BCValueList& getValueList();
|
const BCValueList& getValueList();
|
||||||
|
|
||||||
|
|||||||
@@ -144,11 +144,11 @@ void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
|
|||||||
// Kosmetik
|
// Kosmetik
|
||||||
const BCValue& value = *(valuePtr.get());
|
const BCValue& value = *(valuePtr.get());
|
||||||
|
|
||||||
uint32_t devID = static_cast<uint32_t>(value.getDeviceID());
|
uint32_t devID = static_cast<uint32_t>(value.deviceID());
|
||||||
uint8_t regID = static_cast<uint8_t> (value.getRegisterID());
|
uint8_t regID = static_cast<uint8_t> (value.registerID());
|
||||||
|
|
||||||
// Für den Fehlerfall: Wir senden den alten Wert einfach zurück
|
// Für den Fehlerfall: Wir senden den alten Wert einfach zurück
|
||||||
uint32_t newValue = value.getRawValue();
|
uint32_t newValue = value.rawValue();
|
||||||
BCValue::Flag newState = BCValue::Flag::Failed;
|
BCValue::Flag newState = BCValue::Flag::Failed;
|
||||||
|
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit valueUpdated( value.getDeviceID(), value.getIndexRow(), newState, newValue );
|
emit valueUpdated( value.deviceID(), value.indexRow(), newState, newValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
64
bcvalue.cpp
64
bcvalue.cpp
@@ -75,17 +75,17 @@ void BCValue::setFlag( BCValue::Flag flag, bool state) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BCDevice::ID BCValue::getDeviceID() const noexcept
|
BCDevice::ID BCValue::deviceID() const noexcept
|
||||||
{
|
{
|
||||||
return _deviceID;
|
return _deviceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
BC::ID BCValue::getRegisterID() const noexcept
|
BC::ID BCValue::registerID() const noexcept
|
||||||
{
|
{
|
||||||
return _registerID;
|
return _registerID;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t BCValue::getRawValue() const noexcept
|
uint32_t BCValue::rawValue() const noexcept
|
||||||
{
|
{
|
||||||
return _rawValue;
|
return _rawValue;
|
||||||
}
|
}
|
||||||
@@ -101,6 +101,12 @@ void BCValue::setRawValue(uint32_t newRawValue) const
|
|||||||
// können beliebigen Unsinn enthalten, also müssen wir sie
|
// können beliebigen Unsinn enthalten, also müssen wir sie
|
||||||
// auch skalieren.
|
// auch skalieren.
|
||||||
|
|
||||||
|
if( _valueType == ValueType::Bool )
|
||||||
|
{
|
||||||
|
_rawValue = newRawValue > 0 ? 1 : 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
double value = newRawValue * _factor;
|
double value = newRawValue * _factor;
|
||||||
|
|
||||||
if( _optMin.has_value() && _optMax.has_value() )
|
if( _optMin.has_value() && _optMax.has_value() )
|
||||||
@@ -116,13 +122,13 @@ void BCValue::setRawValue(uint32_t newRawValue) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BCValue::ValueType BCValue::getValueType() const noexcept
|
BCValue::ValueType BCValue::valueType() const noexcept
|
||||||
{
|
{
|
||||||
return _valueType;
|
return _valueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int BCValue::getIndexRow() const noexcept
|
int BCValue::indexRow() const noexcept
|
||||||
{
|
{
|
||||||
return _indexRow;
|
return _indexRow;
|
||||||
}
|
}
|
||||||
@@ -132,31 +138,16 @@ void BCValue::setIndexRow(int newIndexRow)
|
|||||||
_indexRow = newIndexRow;
|
_indexRow = newIndexRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BCValue::getLabel() const
|
QString BCValue::label() const
|
||||||
{
|
{
|
||||||
return _label;
|
return _label;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BCValue::getUnitLabel() const
|
QString BCValue::unitLabel() const
|
||||||
{
|
{
|
||||||
return _unitLabel;
|
return _unitLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
double BCValue::getFactor() const noexcept
|
|
||||||
{
|
|
||||||
return _factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
const OptDouble BCValue::getOptMin() const
|
|
||||||
{
|
|
||||||
return _optMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
const OptDouble BCValue::getOptMax() const
|
|
||||||
{
|
|
||||||
return _optMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCValue::setFromDouble( double value )
|
void BCValue::setFromDouble( double value )
|
||||||
{
|
{
|
||||||
//if( _isReadOnly)
|
//if( _isReadOnly)
|
||||||
@@ -166,7 +157,7 @@ void BCValue::setFromDouble( double value )
|
|||||||
// wir betrachten plain
|
// wir betrachten plain
|
||||||
|
|
||||||
case ValueType::Bool :
|
case ValueType::Bool :
|
||||||
_rawValue = value >0 ? 1 : 0;
|
_rawValue = value > 0 ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ValueType::Plain :
|
case ValueType::Plain :
|
||||||
@@ -207,19 +198,32 @@ double BCValue::calcMinMaxRatio() const
|
|||||||
if (std::abs(range) < 1e-9)
|
if (std::abs(range) < 1e-9)
|
||||||
return ratio;
|
return ratio;
|
||||||
|
|
||||||
|
double value = _rawValue * _factor;
|
||||||
// Die eigentliche Formel
|
// Die eigentliche Formel
|
||||||
ratio = ((_rawValue - min) / range);
|
ratio = ((value - min) / range);
|
||||||
//ratio = (int) qBound( min,ratio, max);
|
|
||||||
}
|
}
|
||||||
return ratio;
|
return ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t BCValue::getScaledValue() const noexcept
|
|
||||||
{
|
|
||||||
double value =_rawValue * _factor;
|
|
||||||
return (uint32_t) value * calcMinMaxRatio();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool BCValue::valuesForSlider( int& value, int& min, int& max ) const
|
||||||
|
{
|
||||||
|
// min & max sind vorraussetzung für den slider
|
||||||
|
if( !_optMin.has_value() || !_optMax.has_value() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// wir erwarten hier, das value zwischen min
|
||||||
|
// und max liegt weil wir das schon bei setRawValue
|
||||||
|
// überprüft haben.
|
||||||
|
|
||||||
|
value = _rawValue * _factor;
|
||||||
|
min = _optMin.value();
|
||||||
|
max = _optMax.value();
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void BCValue::dumpValue() const
|
void BCValue::dumpValue() const
|
||||||
{
|
{
|
||||||
|
|||||||
20
bcvalue.h
20
bcvalue.h
@@ -107,22 +107,20 @@ public:
|
|||||||
bool testFlag( Flag flag ) const;
|
bool testFlag( Flag flag ) const;
|
||||||
void setFlag( Flag flag, bool state=true ) const;
|
void setFlag( Flag flag, bool state=true ) const;
|
||||||
|
|
||||||
BCDevice::ID getDeviceID() const noexcept;
|
BCDevice::ID deviceID() const noexcept;
|
||||||
BC::ID getRegisterID() const noexcept;
|
BC::ID registerID() const noexcept;
|
||||||
|
|
||||||
uint32_t getRawValue() const noexcept;
|
uint32_t rawValue() const noexcept;
|
||||||
uint32_t getScaledValue() const noexcept;
|
|
||||||
void setRawValue(uint32_t newRawValue) const;
|
void setRawValue(uint32_t newRawValue) const;
|
||||||
void setFromDouble( double value );
|
void setFromDouble( double value );
|
||||||
|
|
||||||
ValueType getValueType() const noexcept;
|
ValueType valueType() const noexcept;
|
||||||
int getIndexRow() const noexcept;
|
int indexRow() const noexcept;
|
||||||
void setIndexRow(int newIndexRow);
|
void setIndexRow(int newIndexRow);
|
||||||
QString getLabel() const;
|
QString label() const;
|
||||||
QString getUnitLabel() const;
|
QString unitLabel() const;
|
||||||
double getFactor() const noexcept;
|
|
||||||
const OptDouble getOptMin() const;
|
bool valuesForSlider( int& value, int& min, int& max ) const;
|
||||||
const OptDouble getOptMax() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|||||||
@@ -62,9 +62,16 @@ QWidget* BCValueDelegate::createEditor(QWidget *parent, const QStyleOptionViewIt
|
|||||||
|
|
||||||
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
||||||
|
|
||||||
qDebug() << " --- Create Editor: " << bcValue.getLabel() << " ratio: " << bcValue.calcMinMaxRatio() << " raw: " << bcValue.getRawValue() << " scaled: " << bcValue.getScaledValue();
|
int value,min,max;
|
||||||
|
bool hasData = bcValue.valuesForSlider( value, min, max );
|
||||||
|
if( !hasData )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
auto* valueEditor = new BCValueEditor(bcValue.getScaledValue(), parent);
|
qDebug() << " --- Create Editor: " << bcValue.label() << " value: " << value << " min: " << min << " max: " << max << " ratio:" << bcValue.calcMinMaxRatio()*100.0 << '%';
|
||||||
|
|
||||||
|
auto* valueEditor = new BCValueEditor(parent);
|
||||||
|
valueEditor->setValue( value );
|
||||||
|
valueEditor->setRange( min, max );
|
||||||
|
|
||||||
// Signal für sofortige Updates
|
// Signal für sofortige Updates
|
||||||
connect(valueEditor, &BCValueEditor::valueChanged, this, [this, valueEditor]()
|
connect(valueEditor, &BCValueEditor::valueChanged, this, [this, valueEditor]()
|
||||||
@@ -122,8 +129,15 @@ void BCValueDelegate::paint(QPainter *painter, const QStyleOptionViewItem& optio
|
|||||||
if( row>-1 && row <= _valueList.size() )
|
if( row>-1 && row <= _valueList.size() )
|
||||||
{
|
{
|
||||||
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
||||||
if( !bcValue.isReadOnly())
|
if( !bcValue.isReadOnly() )
|
||||||
paintSliderIndicator(painter,option,bcValue);
|
{
|
||||||
|
if( bcValue.valueType() == BCValue::ValueType::Bool )
|
||||||
|
paintButtonIndicator(painter,option,bcValue);
|
||||||
|
else
|
||||||
|
paintSliderIndicator(painter,option,bcValue);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_rowOpacities.contains(row))
|
if(_rowOpacities.contains(row))
|
||||||
@@ -175,6 +189,11 @@ void BCValueDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionVi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BCValueDelegate::paintButtonIndicator(QPainter* painter, const QStyleOptionViewItem& option, const BCValue& bcValue) const
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Zeichnet eine passiven Slider, um den möglichen Wertebereich des übergebenen BCValue anzuzeigen.
|
* @brief Zeichnet eine passiven Slider, um den möglichen Wertebereich des übergebenen BCValue anzuzeigen.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ protected:
|
|||||||
void updateRow(int row);
|
void updateRow(int row);
|
||||||
void paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, int row) const;
|
void paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, int row) const;
|
||||||
void paintSliderIndicator(QPainter* painter, const QStyleOptionViewItem& option, const BCValue& bcValue) const;
|
void paintSliderIndicator(QPainter* painter, const QStyleOptionViewItem& option, const BCValue& bcValue) const;
|
||||||
|
void paintButtonIndicator(QPainter* painter, const QStyleOptionViewItem& option, const BCValue& bcValue) const;
|
||||||
|
|
||||||
// Das ist ein Quickhack, der Delegate sollte
|
// Das ist ein Quickhack, der Delegate sollte
|
||||||
// nichts über die Originaldaten wissen. Die
|
// nichts über die Originaldaten wissen. Die
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <bcvalue.h>
|
#include <bcvalue.h>
|
||||||
|
|
||||||
|
|
||||||
BCValueEditor::BCValueEditor( int sliderValue, QWidget *parent )
|
BCValueEditor::BCValueEditor( QWidget *parent )
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
@@ -17,8 +17,7 @@ BCValueEditor::BCValueEditor( int sliderValue, QWidget *parent )
|
|||||||
sp.setRetainSizeWhenHidden(true); // <--- Das ist der magische Schalter
|
sp.setRetainSizeWhenHidden(true); // <--- Das ist der magische Schalter
|
||||||
_commitButton->setSizePolicy(sp);
|
_commitButton->setSizePolicy(sp);
|
||||||
|
|
||||||
_slider->setRange(0, 100);
|
|
||||||
_slider->setValue( sliderValue );
|
|
||||||
|
|
||||||
// Wenn Slider bewegt wird -> Signal nach außen senden
|
// Wenn Slider bewegt wird -> Signal nach außen senden
|
||||||
connect(_slider, &QSlider::valueChanged, this, [this](int val)
|
connect(_slider, &QSlider::valueChanged, this, [this](int val)
|
||||||
@@ -51,3 +50,9 @@ void BCValueEditor::setValue(int val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BCValueEditor::setRange( int min, int max )
|
||||||
|
{
|
||||||
|
_slider->setRange( min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ class BCValueEditor : public QWidget, private Ui::BCValueEditor
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit BCValueEditor(int sliderValue, QWidget *parent = nullptr);
|
explicit BCValueEditor(QWidget *parent = nullptr);
|
||||||
|
|
||||||
int getValue() const;
|
int getValue() const;
|
||||||
void setValue(int val);
|
void setValue(int val);
|
||||||
|
void setRange( int min, int max );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|||||||
@@ -148,12 +148,12 @@ QVariant BCValueModel::data(const QModelIndex& index, int role) const
|
|||||||
const BCValue& value = *(_valueList.at( row ).get());
|
const BCValue& value = *(_valueList.at( row ).get());
|
||||||
|
|
||||||
if( col == 0 )
|
if( col == 0 )
|
||||||
return value.getLabel();
|
return value.label();
|
||||||
|
|
||||||
if( col == 1)
|
if( col == 1)
|
||||||
{
|
{
|
||||||
if( role == Qt::DisplayRole )
|
if( role == Qt::DisplayRole )
|
||||||
return QString("%1 %2").arg( value.formatValue(), value.getUnitLabel());
|
return QString("%1 %2").arg( value.formatValue(), value.unitLabel());
|
||||||
|
|
||||||
return value.formatValue();
|
return value.formatValue();
|
||||||
}
|
}
|
||||||
@@ -183,6 +183,9 @@ bool BCValueModel::setData(const QModelIndex& index, const QVariant& variant, in
|
|||||||
{
|
{
|
||||||
if (index.isValid() && role == Qt::EditRole)
|
if (index.isValid() && role == Qt::EditRole)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
qDebug() << " --- SetData: at: " << index.row() << " --- set: " << variant.toString();
|
||||||
|
|
||||||
BCValuePtr value = _valueList[index.row()];
|
BCValuePtr value = _valueList[index.row()];
|
||||||
|
|
||||||
// Wir erwarten hier nur den Value-Teil (vom Slider/Editor)
|
// Wir erwarten hier nur den Value-Teil (vom Slider/Editor)
|
||||||
|
|||||||
Reference in New Issue
Block a user