Public Access
Fixed toggle switch painting, part I
This commit is contained in:
@@ -82,6 +82,9 @@ void BCToggleSwitch::paintEvent(QPaintEvent *)
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
// Option A: Nutze die Standard-Hintergrundfarbe des aktuellen Qt-Themes
|
||||
p.fillRect(rect(), palette().window());
|
||||
|
||||
// --- Farben ---
|
||||
// Tipp: In einem echten Projekt diese Farben als const statics
|
||||
// oder aus der QPalette laden.
|
||||
|
||||
+6
-1
@@ -64,6 +64,11 @@ bool BCValue::isReadOnly() const
|
||||
return _valueFlags.testFlag(BCValue::Flag::ReadOnly);
|
||||
}
|
||||
|
||||
bool BCValue::isBoolean() const
|
||||
{
|
||||
return valueType() == BCValue::ValueType::Bool;
|
||||
}
|
||||
|
||||
bool BCValue::testFlag( BCValue::Flag flag ) const
|
||||
{
|
||||
return _valueFlags.testFlag( flag );
|
||||
@@ -207,7 +212,7 @@ double BCValue::calcMinMaxRatio() const
|
||||
}
|
||||
|
||||
|
||||
bool BCValue::valuesForSlider(ValueRange& valueRange) const
|
||||
bool BCValue::hasValuesForSlider(ValueRange& valueRange) const
|
||||
{
|
||||
valueRange.value = valueRange.min = valueRange.max = 0;
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@ public:
|
||||
void dumpValue() const;
|
||||
bool isWord() const;
|
||||
bool isReadOnly() const;
|
||||
bool isBoolean() const;
|
||||
|
||||
bool testFlag( Flag flag ) const;
|
||||
void setFlag( Flag flag, bool state=true ) const;
|
||||
@@ -137,7 +138,7 @@ public:
|
||||
QString label() const;
|
||||
QString unitLabel() const;
|
||||
|
||||
bool valuesForSlider( ValueRange& valueRange ) const;
|
||||
bool hasValuesForSlider( ValueRange& valueRange ) const;
|
||||
|
||||
QString toString() const;
|
||||
|
||||
|
||||
+59
-47
@@ -45,7 +45,7 @@
|
||||
#include <bcdeviceview.h>
|
||||
#include <bcvaluedelegate.h>
|
||||
#include <bcvalueslider.h>
|
||||
|
||||
#include <bctoggleswitch.h>
|
||||
|
||||
BCValueDelegate::BCValueDelegate(const BCValueList& valueList, BCDeviceView* view)
|
||||
: QStyledItemDelegate{view}, _valueList{valueList}, _view{view}
|
||||
@@ -60,34 +60,41 @@ QWidget* BCValueDelegate::createEditor(QWidget *parent, const QStyleOptionViewIt
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(index)
|
||||
|
||||
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
||||
const BCValue& bcValue = *(_valueList[ index.row() ].get());
|
||||
|
||||
|
||||
//qDebug() << " --- Create Editor: " << bcValue.label() << " value: " << params.value << " min: " << params.min << " max: " << params.max << " ratio:" << bcValue.calcMinMaxRatio()*100.0 << '%';
|
||||
|
||||
if( bcValue.isBoolean() )
|
||||
{
|
||||
auto* toogleSwitch = new BCToggleSwitch{parent};
|
||||
return toogleSwitch;
|
||||
}
|
||||
|
||||
BCValue::ValueRange params;
|
||||
bool hasData = bcValue.valuesForSlider( params );
|
||||
bool hasData = bcValue.hasValuesForSlider( params );
|
||||
|
||||
if( !hasData )
|
||||
return nullptr;
|
||||
|
||||
qDebug() << " --- Create Editor: " << bcValue.label() << " value: " << params.value << " min: " << params.min << " max: " << params.max << " ratio:" << bcValue.calcMinMaxRatio()*100.0 << '%';
|
||||
|
||||
auto* valueEditor = new BCValueSlider(parent);
|
||||
valueEditor->setValueAndRange( params );
|
||||
|
||||
auto* valueSlider = new BCValueSlider{parent};
|
||||
valueSlider->setValueAndRange( params );
|
||||
// Signal für sofortige Updates
|
||||
connect(valueEditor, &BCValueSlider::valueChanged, this, [this, valueEditor]()
|
||||
connect(valueSlider, &BCValueSlider::valueChanged, this, [this, valueSlider]()
|
||||
{
|
||||
// Commit data sofort bei Änderung
|
||||
emit const_cast<BCValueDelegate*>(this)->commitData(valueEditor);
|
||||
emit const_cast<BCValueDelegate*>(this)->commitData(valueSlider);
|
||||
});
|
||||
|
||||
// Signal für sofortige Updates
|
||||
connect(valueEditor, &BCValueSlider::valueCommited, this, [this, valueEditor](int newValue)
|
||||
connect(valueSlider, &BCValueSlider::valueCommited, this, [this, valueSlider](int newValue)
|
||||
{
|
||||
qDebug() << " --- value set:" << newValue;
|
||||
// Commit data sofort bei Änderung
|
||||
//emit const_cast<BCValueDelegate*>(this)->commitData(valueEditor);
|
||||
emit const_cast<BCValueDelegate*>(this)->commitData(valueSlider);
|
||||
});
|
||||
|
||||
return valueEditor;
|
||||
return valueSlider;
|
||||
}
|
||||
|
||||
void BCValueDelegate::setEditorData(QWidget *editor, const QModelIndex& index) const
|
||||
@@ -99,15 +106,26 @@ void BCValueDelegate::setEditorData(QWidget *editor, const QModelIndex& index) c
|
||||
|
||||
}
|
||||
|
||||
|
||||
void BCValueDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
QRect sliderRect = clipToSliderRect( option.rect );
|
||||
editor->setGeometry(sliderRect); // Slider nur über Progress Bar
|
||||
qDebug() << " --- Hier: " << sliderRect;
|
||||
//return QStyledItemDelegate::updateEditorGeometry(editor,option,index);
|
||||
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
||||
QRect editorRect;
|
||||
if( !bcValue.isBoolean())
|
||||
{
|
||||
editorRect = clipToSliderRect( option.rect );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
editorRect = option.rect.adjusted(2,4,0,0);
|
||||
}
|
||||
editor->setGeometry(editorRect);
|
||||
}
|
||||
|
||||
|
||||
void BCValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const
|
||||
{
|
||||
if( index.column() == 1)
|
||||
@@ -128,37 +146,39 @@ void BCValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, c
|
||||
|
||||
void BCValueDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
int row = index.row();
|
||||
|
||||
if( index.column() != 1 )
|
||||
return;
|
||||
if( row<0 || row >= _valueList.size() )
|
||||
int row = index.row();
|
||||
if( index.column() != 1 || row<0 || row >= _valueList.size() )
|
||||
return;
|
||||
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
|
||||
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
||||
//qDebug() << " --- RO?: " << bcValue.label() << " Ro: " << bcValue.isReadOnly() << " Bool: " << bcValue.isBoolean() << ": " << index.flags();
|
||||
|
||||
|
||||
if( bcValue.valueType() == BCValue::ValueType::Bool )
|
||||
if( bcValue.isBoolean() )
|
||||
{
|
||||
opt.text = bcValue.rawValue() == 1 ? "Yes" : "No";
|
||||
paintBooleanValue( painter, opt, bcValue );
|
||||
//opt.text = bcValue.rawValue() == 1 ? "Yes" : "No";
|
||||
//painter->drawText( opt.rect, bcValue.rawValue() == 1 ? "Yes" : "No" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard-Zeichnen (Text, Hintergrund, Selection) durchführen
|
||||
QStyledItemDelegate::paint(painter, opt, index);
|
||||
}
|
||||
|
||||
// Standard-Zeichnen (Text, Hintergrund, Selection) durchführen
|
||||
QStyledItemDelegate::paint(painter, opt, index);
|
||||
|
||||
|
||||
if( !bcValue.isReadOnly() )
|
||||
{
|
||||
// Wir zeichnen boolean Values an toggle switches
|
||||
if( bcValue.valueType() == BCValue::ValueType::Bool )
|
||||
if( bcValue.isBoolean() )
|
||||
paintPlainToggleSwitch(painter, opt, bcValue);
|
||||
else
|
||||
paintPlainSliderIndicator(painter, opt.rect, bcValue.calcMinMaxRatio() );
|
||||
}
|
||||
|
||||
|
||||
if(_rowOpacities.contains(row))
|
||||
paintHighlightRow(painter, opt,index.row());
|
||||
|
||||
@@ -166,29 +186,21 @@ void BCValueDelegate::paint(QPainter *painter, const QStyleOptionViewItem& optio
|
||||
|
||||
void BCValueDelegate::paintBooleanValue( QPainter *painter, const QStyleOptionViewItem& option, const BCValue& bcValue ) const
|
||||
{
|
||||
/*
|
||||
* // 1. Den anzuzeigenden Text aus dem Model holen
|
||||
QString text = index.data(Qt::DisplayRole).toString();
|
||||
|
||||
// Wenn du vorher z. B. '0' oder '1' durch "Aktiv" oder "Inaktiv" ersetzen willst,
|
||||
// könntest du das hier tun:
|
||||
// text = index.data(Qt::DisplayRole).toBool() ? "Aktiv" : "Inaktiv";
|
||||
QRect textRect = option.rect.adjusted( 2,0,0,0);
|
||||
|
||||
// 2. Das Rechteck für den Text berechnen
|
||||
// Wir nehmen das gesamte Rechteck der Zelle und schneiden links Platz für die Checkbox ab.
|
||||
// Angenommen, Checkbox + linkes Padding benötigen ca. 30 Pixel:
|
||||
QRect textRect = option.rect;
|
||||
textRect.setLeft(textRect.left() + 30);
|
||||
// 3. Den tatsächlichen Wert aus dem Model auslesen
|
||||
QString text = bcValue.rawValue() == 1 ? "Yes" : "No";
|
||||
|
||||
// 3. Die korrekte Textfarbe ermitteln (extrem wichtig für die UX!)
|
||||
// Wenn die Zeile markiert ist (Selected), muss der Text meist weiß sein,
|
||||
// ansonsten schwarz (oder je nach System-Theme).
|
||||
QPalette::ColorRole textRole = (option.state & QStyle::State_Selected)
|
||||
QPalette::ColorRole textRole = (option.state & QStyle::State_Selected)
|
||||
? QPalette::HighlightedText
|
||||
: QPalette::Text;
|
||||
|
||||
// 4. Den Text nativ durch den Style zeichnen lassen
|
||||
QApplication::style()->drawItemText(
|
||||
QApplication::style()->drawItemText(
|
||||
painter,
|
||||
textRect,
|
||||
Qt::AlignLeft | Qt::AlignVCenter, // Ausrichtung innerhalb von textRect
|
||||
@@ -196,8 +208,9 @@ QApplication::style()->drawItemText(
|
||||
option.state & QStyle::State_Enabled, // Prüfen, ob die Zelle klickbar/aktiv ist
|
||||
text, // Der zu zeichnende String
|
||||
textRole // Die ermittelte Farb-Rolle
|
||||
);
|
||||
*/
|
||||
);
|
||||
return;
|
||||
/*
|
||||
// 1. Standard-Optionen für die Zelle holen
|
||||
QStyleOptionViewItem opt = option;
|
||||
//initStyleOption(&opt, index);
|
||||
@@ -209,8 +222,6 @@ QApplication::style()->drawItemText(
|
||||
// Wir übergeben nullptr für das Widget, da QStyledItemDelegate ohnehin unabhängig zeichnet
|
||||
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, nullptr);
|
||||
|
||||
// 3. Den tatsächlichen Wert aus dem Model auslesen
|
||||
bool isChecked = bcValue.rawValue() == 1;
|
||||
|
||||
// 4. Optionen für die Checkbox konfigurieren
|
||||
QStyleOptionButton cbOpt;
|
||||
@@ -226,6 +237,7 @@ QApplication::style()->drawItemText(
|
||||
|
||||
// 6. Die native Checkbox zeichnen
|
||||
QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &cbOpt, painter, nullptr);
|
||||
*/
|
||||
}
|
||||
|
||||
QRect BCValueDelegate::clipToSliderRect( const QRect& rect, int buttonOffset ) const
|
||||
@@ -234,7 +246,7 @@ QRect BCValueDelegate::clipToSliderRect( const QRect& rect, int buttonOffset ) c
|
||||
(
|
||||
rect.width() - cTextBlockOffset, // Von rechts: cTextBlockOffset (==130) px (Breite der Progress Bar)
|
||||
0, // Oben: kein Offset
|
||||
-buttonOffset, // Rechts: 8px Padding
|
||||
-buttonOffset, // Rechts: 8px Padding
|
||||
0 // Unten: kein Offset
|
||||
);
|
||||
}
|
||||
|
||||
@@ -168,6 +168,7 @@ Qt::ItemFlags BCValueModel::flags(const QModelIndex& index) const
|
||||
if( row>-1 && row<_valueList.size() )
|
||||
{
|
||||
const BCValue& bcValue = *_valueList[row].get();
|
||||
//qDebug() << " --- flags: " << bcValue.label() << " Ro: " << bcValue.isReadOnly() << " Bool: " << bcValue.isBoolean();
|
||||
flag = bcValue.isReadOnly() ? flag : flag|Qt::ItemIsEditable|Qt::ItemIsEnabled;
|
||||
}
|
||||
return flag;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<Value ID='Cons_Assist_Maxspeed_Flag' Label='Max Limit Enabled' ValueType='Bool' />
|
||||
<Value ID='Cons_Assist_Maxspeed_Hi' Label='Max Speed Limit' UnitLabel='km/h' Factor='0.1' Min='0' Max='70' ValueType='Float'/>
|
||||
|
||||
<Value ID='Cons_Assist_Minspeed_Flag' Label='Min Limit Enabled' ValueType='Bool' />
|
||||
<Value ID='Cons_Assist_Minspeed_Flag' Label='Min Limit Enabled' ValueType='Bool'/>
|
||||
<Value ID='Cons_Assist_Minspeed' Label='Min Speed Limit' UnitLabel='km/h' Min='0' Max='70' ValueType='Float'/>
|
||||
|
||||
<Value ID='Cons_Throttle_Maxspeed_Flag' Label='Throttle Limit Enabled' ValueType='Bool'/>
|
||||
|
||||
Reference in New Issue
Block a user