/*************************************************************************** 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 ***************************************************************************/ #ifndef BCSLIDERSTYLE_H #define BCSLIDERSTYLE_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Fluent Design Slider Style class FluentSliderStyle : public QProxyStyle { public: FluentSliderStyle() : QProxyStyle() {} int pixelMetric(PixelMetric metric, const QStyleOption* option = nullptr, const QWidget* widget = nullptr) const override { 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 subControlRect(ComplexControl cc, const QStyleOptionComplex* opt,SubControl sc, const QWidget* widget) const override { 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 if (slider->orientation == Qt::Horizontal) { 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); } else { int range = slider->maximum - slider->minimum; int pos = slider->sliderPosition - slider->minimum; int pixelRange = rect.height() - handleSize; int pixelPos = (range != 0) ? (pos * pixelRange) / range : 0; return QRect(rect.center().x() - handleSize / 2, rect.bottom() - pixelPos - handleSize, handleSize, handleSize); } } } } return QProxyStyle::subControlRect(cc, opt, sc, widget); } void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override { if (control == CC_Slider) { if (const QStyleOptionSlider* slider = qstyleoption_cast(option)) { painter->setRenderHint(QPainter::Antialiasing); // Fluent Colors QColor accentColor(0, 120, 212); // #0078D4 QColor inactiveColor(138, 136, 134); // #8A8886 QColor bgColor(255, 255, 255); // White background //QColor disabledText = option.palette.color(QPalette::Disabled, QPalette::Text); //painter->setBrush(disabledText); //QColor bgColor = Qt::green;//option->palette.color(QPalette::Base); drawHorizontalFluentSlider(painter, slider, accentColor, inactiveColor, bgColor); return; } } QProxyStyle::drawComplexControl(control, option, painter, widget); } private: void drawHorizontalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider, const QColor& activeColor, const QColor& inactiveColor, const QColor& bgColor) const { QRect groove = slider->rect; QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, nullptr); int grooveHeight = 4; // Track sollte im Widget-Zentrum sein, nicht im groove-Zentrum int grooveY = slider->rect.center().y() - grooveHeight / 2; // Full background track QRect fullTrack(groove.left(), grooveY, groove.width(), grooveHeight); painter->setPen(Qt::NoPen); painter->setBrush(inactiveColor.lighter(150)); painter->drawRoundedRect(fullTrack, grooveHeight / 2, grooveHeight / 2); // Active track (filled portion) int activeWidth = handle.center().x() - groove.left(); QRect activeTrack(groove.left(), grooveY, activeWidth, grooveHeight); painter->setBrush(activeColor); painter->drawRoundedRect(activeTrack, grooveHeight / 2, grooveHeight / 2); // Handle (Thumb) - Fluent style is more subtle int handleSize = 16; QRect thumbRect(handle.center().x() - handleSize / 2, handle.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 = 18; 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); } } }; #endif // BCSLIDERSTYLE_H