From 43508cd69859a9819eadf003c52f05b44583b398 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 29 Mar 2026 23:30:42 +0200 Subject: [PATCH] Fixed slider painting, part III --- bctoggleswitch.cpp | 3 +- bcvalue.h | 2 +- bcvaluedelegate.cpp | 142 +++++++++++++++++--- bcvaluedelegate.h | 13 +- bcvalueslider.cpp | 194 +-------------------------- bcvalueslider.h | 31 +---- bcvalueslider.ui | 4 +- trash/bcvaluesliderold.cpp | 265 +++++++++++++++++++++++++++++++++++++ trash/bcvaluesliderold.h | 67 ++++++++++ trash/bcvaluesliderold.ui | 95 +++++++++++++ 10 files changed, 573 insertions(+), 243 deletions(-) create mode 100644 trash/bcvaluesliderold.cpp create mode 100644 trash/bcvaluesliderold.h create mode 100644 trash/bcvaluesliderold.ui diff --git a/bctoggleswitch.cpp b/bctoggleswitch.cpp index dce8981..f724cc3 100644 --- a/bctoggleswitch.cpp +++ b/bctoggleswitch.cpp @@ -52,7 +52,8 @@ BCToggleSwitch::BCToggleSwitch(QWidget *parent) m_animation->setEasingCurve(QEasingCurve::OutQuad); // Signal verknüpfen - connect(this, &QAbstractButton::toggled, this, [this](bool checked){ + connect(this, &QAbstractButton::toggled, this, [this](bool checked) + { m_animation->stop(); m_animation->setStartValue(m_position); m_animation->setEndValue(checked ? 1.0f : 0.0f); diff --git a/bcvalue.h b/bcvalue.h index 452686a..30045b9 100644 --- a/bcvalue.h +++ b/bcvalue.h @@ -56,7 +56,7 @@ using OptDouble = std::optional; // Enthält den gelesenen Wert oder einen Fehlerstring using TransmitResult = std::expected; -// Funktionsobject, um Werte aus der Transmitterschicht zu holden +// Funktionsobject, um Werte aus der Transmitterschicht zu holen //using ReadValueFunc = std::function; class BCValue diff --git a/bcvaluedelegate.cpp b/bcvaluedelegate.cpp index fc3d34d..e6cf817 100644 --- a/bcvaluedelegate.cpp +++ b/bcvaluedelegate.cpp @@ -99,6 +99,15 @@ 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); +} void BCValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const { if( index.column() == 1) @@ -119,30 +128,118 @@ void BCValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, c void BCValueDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - // Standard-Zeichnen (Text, Hintergrund, Selection) durchführen - QStyledItemDelegate::paint(painter, option, index); - int row = index.row(); + int row = index.row(); if( index.column() != 1 ) return; if( row<0 || row >= _valueList.size() ) return; + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + const BCValue& bcValue = *(_valueList[ index.row()].get()); + + + if( bcValue.valueType() == BCValue::ValueType::Bool ) + { + opt.text = "fitz!"; + qDebug() << " -- YES: " << opt.text; + opt.text = bcValue.rawValue() == 1 ? "Yes" : "No"; + } + + // 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 ) - paintPlainToggleSwitch(painter, option, bcValue); + paintPlainToggleSwitch(painter, opt, bcValue); else - paintPlainSliderIndicator(painter, option.rect, bcValue.calcMinMaxRatio() ); + paintPlainSliderIndicator(painter, opt.rect, bcValue.calcMinMaxRatio() ); } if(_rowOpacities.contains(row)) - paintHighlightRow(painter,option,index.row()); + paintHighlightRow(painter, opt,index.row()); } +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"; + +// 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. 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::HighlightedText + : QPalette::Text; + +// 4. Den Text nativ durch den Style zeichnen lassen +QApplication::style()->drawItemText( + painter, + textRect, + Qt::AlignLeft | Qt::AlignVCenter, // Ausrichtung innerhalb von textRect + option.palette, // Farbpalette der View übernehmen + option.state & QStyle::State_Enabled, // Prüfen, ob die Zelle klickbar/aktiv ist + text, // Der zu zeichnende String + textRole // Die ermittelte Farb-Rolle +); + */ + // 1. Standard-Optionen für die Zelle holen + QStyleOptionViewItem opt = option; + //initStyleOption(&opt, index); + + // 2. Den originalen Text ('0' oder '1') ausblenden, damit er nicht hinter der Checkbox steht + opt.text = ""; + + // Zuerst den Hintergrund der Zelle zeichnen (wichtig für Selektions-Farben etc.) + // 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; + cbOpt.state = isChecked ? QStyle::State_On : QStyle::State_Off; + cbOpt.state |= QStyle::State_Enabled; // Damit die Checkbox nicht ausgegraut/deaktiviert aussieht + + // 5. Größe und Position berechnen (Zentriert in der Zelle) + // Wir fragen das System nach der korrekten Größe für eine Checkbox + QRect checkRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &cbOpt, nullptr); + + // Checkbox exakt in der Mitte des zur Verfügung stehenden Zellenbereichs platzieren + cbOpt.rect = QStyle::alignedRect(option.direction, Qt::AlignLeft| Qt::AlignVCenter, checkRect.size(), option.rect); + + // 6. Die native Checkbox zeichnen + QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &cbOpt, painter, nullptr); +} + +QRect BCValueDelegate::clipToSliderRect( const QRect& rect, int buttonOffset ) const +{ + return rect.adjusted + ( + rect.width() - cTextBlockOffset, // Von rechts: cTextBlockOffset (==130) px (Breite der Progress Bar) + 0, // Oben: kein Offset + -buttonOffset, // Rechts: 8px Padding + 0 // Unten: kein Offset + ); +} /** * @brief Zeichnet der 'Sliderindicator', also den Anteil des Gesamtwerts als Fortschrittsbalken @@ -150,8 +247,29 @@ void BCValueDelegate::paint(QPainter *painter, const QStyleOptionViewItem& optio void BCValueDelegate::paintPlainSliderIndicator(QPainter* painter, const QRect& rect, double ratio )const { - QRect sliderRect = BCValueSlider::clipToSliderRect( rect ); - BCValueSlider::paintSliderIndicator(painter, sliderRect, ratio ); + QRect sliderRect = clipToSliderRect( rect, 35 ); + //BCValueSliderOld::paintSliderIndicator(painter, sliderRect, ratio ); + // Kleinen Slider-Indikator zeichnen + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + QRect barRect = sliderRect; + + int yOffset = sliderRect.height()/2; + barRect.setY( rect.y() + yOffset - 3 ); + barRect.setHeight( 6); + + // Mini Progress Bar: der Gesamtbereich + painter->setPen(Qt::NoPen); + painter->setBrush(QColor(0xE0E0E0)); + painter->drawRoundedRect(barRect, 4, 4); + + // Mini Progress Bar: der Wertebereich + barRect.setWidth( ratio * barRect.width() ); + painter->setBrush(QColor(0x0078D4)); + painter->drawRoundedRect(barRect, 4, 4); + + painter->restore(); } void BCValueDelegate::paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, int row) const @@ -182,14 +300,6 @@ void BCValueDelegate::paintHighlightRow(QPainter* painter, const QStyleOptionVie } -void BCValueDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex& index) const -{ - Q_UNUSED(index) - QRect baseRect = option.rect.adjusted( 0,0,0 + BCValueSlider::cToolIconOffset, 0 ); - QRect sliderRect = BCValueSlider::clipToSliderRect( baseRect ); - editor->setGeometry(sliderRect); // Slider nur über Progress Bar -} - void BCValueDelegate::paintPlainToggleSwitch(QPainter* painter, const QStyleOptionViewItem& option, const BCValue& bcValue) const { diff --git a/bcvaluedelegate.h b/bcvaluedelegate.h index c4209b3..2776de3 100644 --- a/bcvaluedelegate.h +++ b/bcvaluedelegate.h @@ -51,11 +51,11 @@ public: explicit BCValueDelegate(const BCValueList& valueList, BCDeviceView* view ); // Zuständig für den Edit-Modus (Doppelklick) - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const override; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; void setEditorData(QWidget *editor, const QModelIndex& index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const override; - void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex& index) const override; - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + void paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; void clearAllHighlights(); @@ -71,9 +71,9 @@ protected: void paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, int row) const; void paintPlainToggleSwitch(QPainter* painter, const QStyleOptionViewItem& option, const BCValue& bcValue) const; void paintPlainSliderIndicator(QPainter* painter, const QRect& rect, double ratio ) const; - // Das ist ein Quickhack, der Delegate sollte - // nichts über die Originaldaten wissen. Die - // Datenbeschaffung ist alleine Sache des Models. + void paintBooleanValue( QPainter *painter, const QStyleOptionViewItem& option, const BCValue& bcValue ) const; + + QRect clipToSliderRect(const QRect& rect, int buttonOffset = 0) const; const BCValueList& _valueList; BCDeviceView* _view{}; @@ -83,6 +83,7 @@ protected: QHash _rowOpacities; QHash _rowAnimations; + static constexpr int cTextBlockOffset = 160; }; diff --git a/bcvalueslider.cpp b/bcvalueslider.cpp index 494e67c..4df2e27 100644 --- a/bcvalueslider.cpp +++ b/bcvalueslider.cpp @@ -41,7 +41,7 @@ BCValueSlider::BCValueSlider( QWidget *parent ) setupUi(this); // wir wollen ja modern sein - _sliderStyle = std::make_unique(); + //_sliderStyle = std::make_unique(); //_slider->setStyle(_sliderStyle.get()); setAutoFillBackground(true); @@ -51,15 +51,15 @@ BCValueSlider::BCValueSlider( QWidget *parent ) // Wenn Slider bewegt wird -> Signal nach außen senden connect(_slider, &QSlider::valueChanged, this, [this](int val) - { - emit valueChanged(val); - }); + { + emit valueChanged(val); + }); // Wenn Reset gedrückt wird -> Slider auf 0 (löst auch valueChanged aus) connect(_commitButton, &QPushButton::clicked, this, [this]() - { - emit valueCommited( value() ); - }); + { + emit valueCommited( value() ); + }); } @@ -83,183 +83,3 @@ void BCValueSlider::setValueAndRange( const BCValue::ValueRange& params ) } -QRect BCValueSlider::clipToSliderRect( const QRect& rect) -{ - return rect.adjusted - ( - rect.width() - cTextBlockOffset, // Von rechts: cTextBlockOffset (==130) px (Breite der Progress Bar) - 0, // Oben: kein Offset - -(cPaddingRight +24 ), // Rechts: 8px Padding - 0 // Unten: kein Offset - ); -} - - -/** - * @brief Zeichnet eine passiven Slider, um den möglichen Wertebereich des übergebenen BCValue anzuzeigen. - */ - -void BCValueSlider::paintSliderIndicator(QPainter* painter, const QRect& rect, double ratio ) -{ - // Kleinen Slider-Indikator zeichnen - painter->save(); - painter->setRenderHint(QPainter::Antialiasing); - - QRect barRect = rect; - - const int third = rect.height() / 3; - - barRect.setY( rect.y() + third); - barRect.setHeight( third ); - - // Mini Progress Bar: der Gesamtbereich - painter->setPen(Qt::NoPen); - painter->setBrush(QColor(0xE0E0E0)); - painter->drawRoundedRect(barRect, 2, 2); - - // Mini Progress Bar: der Wertebereich - barRect.setWidth( ratio * barRect.width() ); - painter->setBrush(QColor(0x0078D4)); - painter->drawRoundedRect(barRect, 2, 2); - - painter->restore(); -} - - - -BCValueSlider::BCValueSliderStyle::BCValueSliderStyle() - : QProxyStyle() -{ - -} - -int BCValueSlider::BCValueSliderStyle::pixelMetric(PixelMetric metric, const QStyleOption* option, const QWidget* widget ) const -{ - switch (metric) - { - case PM_SliderThickness: - return 24; // Höhe für horizontalen Slider - case PM_SliderLength: - return 16; // Handle-Größe - case PM_SliderControlThickness: - return 16; - case PM_SliderSpaceAvailable: - if (option) - { - if (const QStyleOptionSlider* sliderOpt = qstyleoption_cast(option)) - { - return sliderOpt->rect.width() - 20; - } - } - return QProxyStyle::pixelMetric(metric, option, widget); - - default: - return QProxyStyle::pixelMetric(metric, option, widget); - } -} - -QRect BCValueSlider::BCValueSliderStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex* opt,SubControl sc, const QWidget* widget) const -{ - if (cc == CC_Slider) - { - if (const QStyleOptionSlider* slider = qstyleoption_cast(opt)) - { - QRect rect = slider->rect; - int handleSize = 16; - - if (sc == SC_SliderHandle) - { - // Handle Position korrekt berechnen - int range = slider->maximum - slider->minimum; - int pos = slider->sliderPosition - slider->minimum; - int pixelRange = rect.width() - handleSize; - int pixelPos = (range != 0) ? (pos * pixelRange) / range : 0; - - return QRect(rect.x() + pixelPos, rect.center().y() - handleSize / 2, handleSize, handleSize); - } - } - } - return QProxyStyle::subControlRect(cc, opt, sc, widget); -} - -void BCValueSlider::BCValueSliderStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const -{ - if (control == CC_Slider) - { - if (const QStyleOptionSlider* slider = qstyleoption_cast(option)) { - painter->setRenderHint(QPainter::Antialiasing); - - // Fluent Colors - QColor accentColor(0, 120, 212); // #0078D4 - QColor bgColor(255, 255, 255); // White background - drawHorizontalFluentSlider(painter, slider, accentColor, bgColor); - return; - } - } - QProxyStyle::drawComplexControl(control, option, painter, widget); -} - - -void BCValueSlider::BCValueSliderStyle::drawHorizontalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider, - const QColor& activeColor, - const QColor& bgColor) const -{ - QRect groove = slider->rect; - - - - paintSliderIndicator(painter, groove, 0.5 ); - - painter->setBrush(Qt::red); - QRect handleRect = subControlRect(CC_Slider, slider, SC_SliderHandle, nullptr); - // Das 'subControlRect' für den SC_SliderHandle ist _nicht_ mittig - - handleRect.setY( handleRect.y() + 2 ); - - qDebug() << " --- drawHorizontalFluentSlider" << groove << " Handle: " << handleRect; - - painter->drawRect(handleRect); - - return; - - // Handle (Thumb) - Fluent style is more subtle - int handleSize = 14; - QRect thumbRect(handleRect.center().x() - handleSize / 2, - handleRect.center().y() - handleSize / 2, - handleSize, handleSize); - - /* - // Hover effect - subtle glow - if (slider->state & State_MouseOver) - { - painter->setBrush(QColor(activeColor.red(), activeColor.green(), - activeColor.blue(), 30)); - int glowSize = 16; - QRect glow(handle.center().x() - glowSize / 2, - handle.center().y() - glowSize / 2, - glowSize, glowSize); - painter->drawEllipse(glow); - } - */ - - // Thumb - painter->setBrush(bgColor); - painter->setPen(QPen(activeColor, 2)); - painter->drawEllipse(thumbRect); - - /* - // Inner circle for pressed state - if (slider->state & State_Sunken) - { - int innerSize = 6; - QRect inner(handle.center().x() - innerSize / 2, - handle.center().y() - innerSize / 2, - innerSize, innerSize); - painter->setPen(Qt::NoPen); - painter->setBrush(activeColor); - painter->drawEllipse(inner); - } -*/ -} - - diff --git a/bcvalueslider.h b/bcvalueslider.h index e001ce9..a59c3a7 100644 --- a/bcvalueslider.h +++ b/bcvalueslider.h @@ -18,6 +18,7 @@ class BCValue; class BCValueSlider : public QWidget, private Ui::BCValueSlider { + Q_OBJECT public: @@ -27,41 +28,11 @@ public: int value() const; void setValueAndRange( const BCValue::ValueRange& params ); - // helper functions - static QRect clipToSliderRect( const QRect& rect); - static void paintSliderIndicator(QPainter* painter, const QRect& rect, double ratio ); - - static constexpr int cToolIconOffset = 24; - signals: void valueChanged(int value); void valueCommited(int value); - -protected: - - // Fluent Design Slider Style - class BCValueSliderStyle : public QProxyStyle - { - - public: - - BCValueSliderStyle(); - - int pixelMetric(PixelMetric metric, const QStyleOption* option = nullptr, const QWidget* widget = nullptr) const override; - - QRect subControlRect(ComplexControl cc, const QStyleOptionComplex* opt, SubControl sc, const QWidget* widget) const override; - void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override; - void drawHorizontalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider, const QColor& activeColor, const QColor& bgColor) const; - - }; - - static constexpr int cTextBlockOffset = 130; - static constexpr int cPaddingRight = 8; - static constexpr int cSliderWidth = 117; - - std::unique_ptr _sliderStyle; }; #endif // BC_VALUESLIDER_H diff --git a/bcvalueslider.ui b/bcvalueslider.ui index 4f15512..0c03e50 100644 --- a/bcvalueslider.ui +++ b/bcvalueslider.ui @@ -1,7 +1,7 @@ - BCValueSlider - + BCValueSliderOld + 0 diff --git a/trash/bcvaluesliderold.cpp b/trash/bcvaluesliderold.cpp new file mode 100644 index 0000000..e059914 --- /dev/null +++ b/trash/bcvaluesliderold.cpp @@ -0,0 +1,265 @@ +/*************************************************************************** + + BionxControl + © 2025 -2026 christoph holzheuer + christoph.holzheuer@gmail.com + + Using: + + mhs_can_drv.c + © 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany + Klaus Demlehner, klaus@mhs-elektronik.de + @see www.mhs-elektronik.de + + Based on Bionx data type descriptions from: + + BigXionFlasher USB V 0.2.4 rev. 97 + © 2011-2013 by Thomas Koenig + @see www.bigxionflasher.org + + Bionx Bike Info + © 2018 Thorsten Schmidt (tschmidt@ts-soft.de) + @see www.ts-soft.de + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + @see https://github.com/bikemike/bionx-bikeinfo + + ***************************************************************************/ + + +#include + +#include + + +BCValueSliderOld::BCValueSliderOld( QWidget *parent ) + : QWidget(parent) +{ + setupUi(this); + + // wir wollen ja modern sein + _sliderStyle = std::make_unique(); + //_slider->setStyle(_sliderStyle.get()); + setAutoFillBackground(true); + + QSizePolicy sp = _commitButton->sizePolicy(); + sp.setRetainSizeWhenHidden(true); // <--- Das ist der magische Schalter + _commitButton->setSizePolicy(sp); + + // Wenn Slider bewegt wird -> Signal nach außen senden + connect(_slider, &QSlider::valueChanged, this, [this](int val) + { + emit valueChanged(val); + }); + + // Wenn Reset gedrückt wird -> Slider auf 0 (löst auch valueChanged aus) + connect(_commitButton, &QPushButton::clicked, this, [this]() + { + emit valueCommited( value() ); + }); + +} + +int BCValueSliderOld::value() const +{ + return _slider->value(); +} + +void BCValueSliderOld::setValueAndRange( const BCValue::ValueRange& params ) +{ + _slider->setRange( params.min, params.max); + // Block Signals verhindern Endlosschleifen, falls das Model + // das Widget während des Updates neu setzt (passiert manchmal bei Live-Updates). + if (params.value != _slider->value()) + { + bool blocked = _slider->blockSignals(true); + _slider->setValue(params.value); + _slider->blockSignals(blocked); + } + +} + + +QRect BCValueSliderOld::clipToSliderRect( const QRect& rect) +{ + return rect.adjusted + ( + rect.width() - cTextBlockOffset, // Von rechts: cTextBlockOffset (==130) px (Breite der Progress Bar) + 0, // Oben: kein Offset + -(cPaddingRight +24 ), // Rechts: 8px Padding + 0 // Unten: kein Offset + ); +} + + +/** + * @brief Zeichnet eine passiven Slider, um den möglichen Wertebereich des übergebenen BCValue anzuzeigen. + */ + +void BCValueSliderOld::paintSliderIndicator(QPainter* painter, const QRect& rect, double ratio ) +{ + // Kleinen Slider-Indikator zeichnen + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + QRect barRect = rect; + + const int third = rect.height() / 3; + + barRect.setY( rect.y() + third); + barRect.setHeight( third ); + + // Mini Progress Bar: der Gesamtbereich + painter->setPen(Qt::NoPen); + painter->setBrush(QColor(0xE0E0E0)); + painter->drawRoundedRect(barRect, 2, 2); + + // Mini Progress Bar: der Wertebereich + barRect.setWidth( ratio * barRect.width() ); + painter->setBrush(QColor(0x0078D4)); + painter->drawRoundedRect(barRect, 2, 2); + + painter->restore(); +} + + + +BCValueSliderOld::BCValueSliderStyle::BCValueSliderStyle() + : QProxyStyle() +{ + +} + +int BCValueSliderOld::BCValueSliderStyle::pixelMetric(PixelMetric metric, const QStyleOption* option, const QWidget* widget ) const +{ + switch (metric) + { + case PM_SliderThickness: + return 24; // Höhe für horizontalen Slider + case PM_SliderLength: + return 16; // Handle-Größe + case PM_SliderControlThickness: + return 16; + case PM_SliderSpaceAvailable: + if (option) + { + if (const QStyleOptionSlider* sliderOpt = qstyleoption_cast(option)) + { + return sliderOpt->rect.width() - 20; + } + } + return QProxyStyle::pixelMetric(metric, option, widget); + + default: + return QProxyStyle::pixelMetric(metric, option, widget); + } +} + +QRect BCValueSliderOld::BCValueSliderStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex* opt,SubControl sc, const QWidget* widget) const +{ + if (cc == CC_Slider) + { + if (const QStyleOptionSlider* slider = qstyleoption_cast(opt)) + { + QRect rect = slider->rect; + int handleSize = 16; + + if (sc == SC_SliderHandle) + { + // Handle Position korrekt berechnen + int range = slider->maximum - slider->minimum; + int pos = slider->sliderPosition - slider->minimum; + int pixelRange = rect.width() - handleSize; + int pixelPos = (range != 0) ? (pos * pixelRange) / range : 0; + + return QRect(rect.x() + pixelPos, rect.center().y() - handleSize / 2, handleSize, handleSize); + } + } + } + return QProxyStyle::subControlRect(cc, opt, sc, widget); +} + +void BCValueSliderOld::BCValueSliderStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const +{ + if (control == CC_Slider) + { + if (const QStyleOptionSlider* slider = qstyleoption_cast(option)) { + painter->setRenderHint(QPainter::Antialiasing); + + // Fluent Colors + QColor accentColor(0, 120, 212); // #0078D4 + QColor bgColor(255, 255, 255); // White background + drawHorizontalFluentSlider(painter, slider, accentColor, bgColor); + return; + } + } + QProxyStyle::drawComplexControl(control, option, painter, widget); +} + + +void BCValueSliderOld::BCValueSliderStyle::drawHorizontalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider, + const QColor& activeColor, + const QColor& bgColor) const +{ + QRect groove = slider->rect; + + + + paintSliderIndicator(painter, groove, 0.5 ); + + painter->setBrush(Qt::red); + QRect handleRect = subControlRect(CC_Slider, slider, SC_SliderHandle, nullptr); + // Das 'subControlRect' für den SC_SliderHandle ist _nicht_ mittig + + handleRect.setY( handleRect.y() + 2 ); + + qDebug() << " --- drawHorizontalFluentSlider" << groove << " Handle: " << handleRect; + + painter->drawRect(handleRect); + + return; + + // Handle (Thumb) - Fluent style is more subtle + int handleSize = 14; + QRect thumbRect(handleRect.center().x() - handleSize / 2, + handleRect.center().y() - handleSize / 2, + handleSize, handleSize); + + /* + // Hover effect - subtle glow + if (slider->state & State_MouseOver) + { + painter->setBrush(QColor(activeColor.red(), activeColor.green(), + activeColor.blue(), 30)); + int glowSize = 16; + QRect glow(handle.center().x() - glowSize / 2, + handle.center().y() - glowSize / 2, + glowSize, glowSize); + painter->drawEllipse(glow); + } + */ + + // Thumb + painter->setBrush(bgColor); + painter->setPen(QPen(activeColor, 2)); + painter->drawEllipse(thumbRect); + + /* + // Inner circle for pressed state + if (slider->state & State_Sunken) + { + int innerSize = 6; + QRect inner(handle.center().x() - innerSize / 2, + handle.center().y() - innerSize / 2, + innerSize, innerSize); + painter->setPen(Qt::NoPen); + painter->setBrush(activeColor); + painter->drawEllipse(inner); + } +*/ +} + + diff --git a/trash/bcvaluesliderold.h b/trash/bcvaluesliderold.h new file mode 100644 index 0000000..9ac107b --- /dev/null +++ b/trash/bcvaluesliderold.h @@ -0,0 +1,67 @@ +#ifndef BC_VALUESLIDER_H +#define BC_VALUESLIDER_H + + +#include +#include +#include +#include +#include + +#include +#include + +class QSlider; +class QPushButton; +class BCValue; + + +class BCValueSliderOld : public QWidget, private Ui::BCValueSliderOld +{ + Q_OBJECT + +public: + + explicit BCValueSliderOld(QWidget *parent = nullptr); + + int value() const; + void setValueAndRange( const BCValue::ValueRange& params ); + + // helper functions + static QRect clipToSliderRect( const QRect& rect); + static void paintSliderIndicator(QPainter* painter, const QRect& rect, double ratio ); + + static constexpr int cToolIconOffset = 24; + +signals: + + void valueChanged(int value); + void valueCommited(int value); + + +protected: + + // Fluent Design Slider Style + class BCValueSliderStyle : public QProxyStyle + { + + public: + + BCValueSliderStyle(); + + int pixelMetric(PixelMetric metric, const QStyleOption* option = nullptr, const QWidget* widget = nullptr) const override; + + QRect subControlRect(ComplexControl cc, const QStyleOptionComplex* opt, SubControl sc, const QWidget* widget) const override; + void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override; + void drawHorizontalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider, const QColor& activeColor, const QColor& bgColor) const; + + }; + + static constexpr int cTextBlockOffset = 130; + static constexpr int cPaddingRight = 8; + static constexpr int cSliderWidth = 117; + + std::unique_ptr _sliderStyle; +}; + +#endif // BC_VALUESLIDER_H diff --git a/trash/bcvaluesliderold.ui b/trash/bcvaluesliderold.ui new file mode 100644 index 0000000..0c03e50 --- /dev/null +++ b/trash/bcvaluesliderold.ui @@ -0,0 +1,95 @@ + + + BCValueSliderOld + + + + 0 + 0 + 111 + 24 + + + + + 60 + 24 + + + + Form + + + + 0 + + + QLayout::SizeConstraint::SetMinimumSize + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Orientation::Horizontal + + + + + + + + 24 + 24 + + + + + 16777212 + 16777215 + + + + PointingHandCursor + + + + + + + :/update.png:/update.png + + + + 24 + 24 + + + + QToolButton::ToolButtonPopupMode::InstantPopup + + + Qt::ToolButtonStyle::ToolButtonIconOnly + + + true + + + + + + + + + +