235 lines
6.3 KiB
C++
235 lines
6.3 KiB
C++
/***************************************************************************
|
|
|
|
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 <info@bigxionflasher.org>
|
|
@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 "bctoggleswitch.h"
|
|
|
|
#include <QPainter>
|
|
#include <QPropertyAnimation>
|
|
#include <QEasingCurve>
|
|
#include <QEnterEvent>
|
|
#include <QEvent>
|
|
|
|
BCToggleSwitch::BCToggleSwitch(QWidget *parent)
|
|
: QAbstractButton(parent)
|
|
, m_position(0.0f)
|
|
{
|
|
setCheckable(true);
|
|
setCursor(Qt::PointingHandCursor);
|
|
|
|
// Widget ist jetzt mit setGeometry / Layouts skalierbar
|
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
|
|
|
// Animation initialisieren
|
|
m_animation = new QPropertyAnimation(this, "position", this);
|
|
m_animation->setDuration(200);
|
|
m_animation->setEasingCurve(QEasingCurve::OutQuad);
|
|
|
|
// Signal verknüpfen
|
|
connect(this, &QAbstractButton::toggled, this, [this](bool checked)
|
|
{
|
|
m_animation->stop();
|
|
m_animation->setStartValue(m_position);
|
|
m_animation->setEndValue(checked ? 1.0f : 0.0f);
|
|
m_animation->start();
|
|
});
|
|
}
|
|
|
|
float BCToggleSwitch::position() const
|
|
{
|
|
return m_position;
|
|
}
|
|
|
|
void BCToggleSwitch::setPosition(float pos)
|
|
{
|
|
m_position = pos;
|
|
update(); // Trigger Repaint
|
|
}
|
|
|
|
QSize BCToggleSwitch::sizeHint() const
|
|
{
|
|
return QSize(44, 22);
|
|
}
|
|
|
|
QSize BCToggleSwitch::minimumSizeHint() const
|
|
{
|
|
return QSize(30, 16);
|
|
}
|
|
|
|
void BCToggleSwitch::paintEvent(QPaintEvent *)
|
|
{
|
|
QPainter p(this);
|
|
p.setRenderHint(QPainter::Antialiasing);
|
|
|
|
QRect ownRect = rect();
|
|
|
|
// Standard-Hintergrundfarbe des aktuellen Qt-Themes
|
|
p.fillRect(ownRect, palette().window());
|
|
|
|
// Auf deaktivierten Zustand prüfen und die statische Methode aufrufen
|
|
if (!isEnabled()) {
|
|
paintToggleIndicator(&p, ownRect, isChecked(), m_position, palette());
|
|
return;
|
|
}
|
|
|
|
// --- Farben aus der aktuellen Palette ---
|
|
QColor onColor = palette().color(QPalette::Highlight);
|
|
QColor offBorderColor = palette().color(QPalette::Mid);
|
|
QColor offKnobColor = palette().color(QPalette::Dark);
|
|
QColor knobOnColor = palette().color(QPalette::HighlightedText);
|
|
|
|
// Proportionale Werte aus der Widget-Höhe ableiten
|
|
qreal h = ownRect.height();
|
|
qreal radius = h / 2.0;
|
|
qreal penW = qMax(1.0, h / 14.0); // Strichstärke skaliert mit
|
|
qreal padding = qMax(2.0, h * 0.14); // Innenabstand skaliert mit
|
|
|
|
// 1. Hintergrund (Track) zeichnen
|
|
p.setPen(Qt::NoPen);
|
|
|
|
if (isChecked() || m_position > 0.5f)
|
|
{
|
|
// AN-Zustand: Hintergrund gefüllt
|
|
p.setBrush(onColor);
|
|
p.drawRoundedRect(ownRect, radius, radius);
|
|
}
|
|
else
|
|
{
|
|
// AUS-Zustand: Nur Rahmen
|
|
p.setBrush(Qt::NoBrush);
|
|
|
|
// Hover-Status prüfen
|
|
if (underMouse())
|
|
p.setPen(QPen(offBorderColor.darker(120), penW));
|
|
else
|
|
p.setPen(QPen(offBorderColor, penW));
|
|
|
|
// Rechteck etwas verkleinern, damit der Rahmen nicht abgeschnitten wird
|
|
qreal inset = penW / 2.0;
|
|
p.drawRoundedRect(QRectF(ownRect).adjusted(inset, inset, -inset, -inset),
|
|
radius - inset, radius - inset);
|
|
}
|
|
|
|
// 2. Knopf (Thumb) zeichnen
|
|
qreal knobDiameter = h - (2 * padding);
|
|
|
|
// Interpolation der Position
|
|
qreal startX = padding;
|
|
qreal endX = ownRect.width() - knobDiameter - padding;
|
|
qreal currentX = startX + (m_position * (endX - startX));
|
|
|
|
QRectF knobRect(currentX, padding, knobDiameter, knobDiameter);
|
|
|
|
if (isChecked() || m_position > 0.5f)
|
|
{
|
|
p.setBrush(knobOnColor);
|
|
}
|
|
else
|
|
{
|
|
if (underMouse())
|
|
p.setBrush(offKnobColor.darker(110));
|
|
else
|
|
p.setBrush(offKnobColor);
|
|
}
|
|
|
|
p.setPen(Qt::NoPen);
|
|
p.drawEllipse(knobRect);
|
|
}
|
|
|
|
void BCToggleSwitch::paintToggleIndicator(QPainter* p, const QRect& rect, bool isChecked, float position, const QPalette& palette)
|
|
{
|
|
// --- Farben für den deaktivierten Zustand aus der Palette ---
|
|
QColor disabledBorderColor = palette.color(QPalette::Disabled, QPalette::Mid);
|
|
QColor disabledKnobColor = palette.color(QPalette::Disabled, QPalette::Dark);
|
|
QColor disabledOnColor = palette.color(QPalette::Disabled, QPalette::Highlight);
|
|
QColor disabledKnobOnColor = palette.color(QPalette::Disabled, QPalette::HighlightedText);
|
|
|
|
QRectF r(rect);
|
|
qreal h = r.height();
|
|
qreal radius = h / 2.0;
|
|
qreal penW = qMax(1.0, h / 14.0);
|
|
qreal padding = qMax(2.0, h * 0.14);
|
|
|
|
// 1. Hintergrund (Track) zeichnen
|
|
p->setPen(Qt::NoPen);
|
|
|
|
if (isChecked || position > 0.5f)
|
|
{
|
|
// AN-Zustand (deaktiviert)
|
|
p->setBrush(disabledOnColor);
|
|
p->drawRoundedRect(r, radius, radius);
|
|
}
|
|
else
|
|
{
|
|
// AUS-Zustand (deaktiviert)
|
|
p->setBrush(Qt::NoBrush);
|
|
p->setPen(QPen(disabledBorderColor, penW));
|
|
qreal inset = penW / 2.0;
|
|
p->drawRoundedRect(r.adjusted(inset, inset, -inset, -inset),
|
|
radius - inset, radius - inset);
|
|
}
|
|
|
|
// 2. Knopf (Thumb) zeichnen
|
|
qreal knobDiameter = h - (2 * padding);
|
|
|
|
// X- und Y-Offsets des übergebenen Rects berücksichtigen!
|
|
qreal startX = r.x() + padding;
|
|
qreal endX = r.x() + r.width() - knobDiameter - padding;
|
|
qreal currentX = startX + (position * (endX - startX));
|
|
|
|
QRectF knobRect(currentX, r.y() + padding, knobDiameter, knobDiameter);
|
|
|
|
p->setPen(Qt::NoPen);
|
|
|
|
if (isChecked || position > 0.5f)
|
|
{
|
|
p->setBrush(disabledKnobOnColor);
|
|
}
|
|
else
|
|
{
|
|
p->setBrush(disabledKnobColor);
|
|
}
|
|
|
|
p->drawEllipse(knobRect);
|
|
}
|
|
|
|
void BCToggleSwitch::enterEvent(QEnterEvent *event)
|
|
{
|
|
update(); // Für Hover-Effekt neu zeichnen
|
|
QAbstractButton::enterEvent(event);
|
|
}
|
|
|
|
void BCToggleSwitch::leaveEvent(QEvent *event)
|
|
{
|
|
update(); // Hover entfernen
|
|
QAbstractButton::leaveEvent(event);
|
|
}
|