Files
raDIYo/swtoggleswitch.cpp
2025-08-05 22:36:00 +02:00

200 lines
5.0 KiB
C++

/***************************************************************************
source::worx libWidgets
Copyright © 2021 c.holzheuer
chris@sourceworx.org
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 2 of the License, or
(at your option) any later version.
***************************************************************************/
#include <QPainterPath>
#include <QEvent>
#include <QCoreApplication>
#include <QPropertyAnimation>
#include <QPainter>
#include <QMouseEvent>
#include <QColor>
#include <QPen>
#include <QDebug>
#include <swtoggleswitch.h>
#include <raDIYoglobals.h>
/**
* @brief Standardkonstruktor.
* @param parent das Elternwidget
* @param trackRadius Radius der Hintergrundrundung, default 16 px.
* @param thumbRadius Radius des Schalterelements, default 20 px.
*/
SWToggleSwitch::SWToggleSwitch( QWidget* parent, int trackRadius, int thumbRadius )
: QAbstractButton( parent )
{
setCheckable( true );
setAcceptDial( false );
//setSizePolicy(QSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed));
_trackRadius = trackRadius;
_thumbRadius = thumbRadius;
_animation = new QPropertyAnimation(this);
_animation->setTargetObject(this);
_margin = 0 > (_thumbRadius - _trackRadius) ? 0 : (_thumbRadius - _trackRadius);
_baseOffset = _thumbRadius > _trackRadius ? _thumbRadius : _trackRadius;
_endOffset.insert( true, 4 * _trackRadius + 2 * _margin - _baseOffset); // width - offset
_endOffset.insert( false, _baseOffset);
_offset = _baseOffset;
QPalette palette = this->palette();
_trackColor.insert( true, QBrush( Qt::lightGray ) );
_trackColor.insert( false, palette.dark() );
//_thumbColor.insert( true, palette.highlight());
_thumbColor.insert( true, QBrush( Qt::gray ) );
//_thumbColor.insert( false, palette.light());
_thumbColor.insert( false, QBrush( Qt::darkGray ) );
_textColor.insert( true, palette.highlightedText().color());
_textColor.insert( false, palette.dark().color());
_thumbText.insert( true, "");
_thumbText.insert( false, "");
_opacity = 0.5;
// semi schlimmer hack: clicks auf mich weiterleiten
connect( this, &QAbstractButton::clicked, this, [=]{ emit widgetClicked(this); } );
}
SWToggleSwitch::~SWToggleSwitch()
{
delete _animation;
}
/**
* @brief Ermittelt die ideale Widgetgrösse.
*/
QSize SWToggleSwitch::sizeHint() const
{
int w = 4 * _trackRadius + 2 * _margin;
int h = 2 * _trackRadius + 2 * _margin;
return QSize(w, h);
}
/**
* @brief Setzt die geometrischen Vorgabewerte.
* @param trackRadius Radius der Hintergrundrundung.
* @param thumbRadius Radius des Schalterelements.
*/
void SWToggleSwitch::setTrackAndThumbRadius( int trackRadius, int thumbRadius )
{
_trackRadius = trackRadius;
_thumbRadius = thumbRadius;
}
/**
* @brief Zeichnet das Widget.
*/
void SWToggleSwitch::paintEvent( QPaintEvent* )
{
QPainter painter( this );
QPainter::RenderHints m_paintFlags = QPainter::RenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing);
painter.setRenderHints(m_paintFlags, true);
painter.setPen(Qt::NoPen);
bool check = isChecked();
qreal trackOpacity = _opacity;
qreal thumbOpacity = 1.0;
QBrush trackBrush;
QBrush thumbBrush;
if( isEnabled() )
{
trackBrush = _trackColor[check];
thumbBrush = _thumbColor[check];
}
else
{
trackOpacity *= 0.8;
trackBrush = this->palette().shadow();
thumbBrush = this->palette().mid();
}
painter.setBrush(trackBrush);
painter.setOpacity(trackOpacity);
painter.drawRoundedRect( _margin, _margin, width() - 2 * _margin, height() - 2 * _margin, _trackRadius, _trackRadius );
painter.setBrush( thumbBrush );
painter.setOpacity( thumbOpacity );
painter.drawEllipse( _offset - _thumbRadius, _baseOffset - _thumbRadius, 2 * _thumbRadius, 2 * _thumbRadius );
drawMark( this );
}
void SWToggleSwitch::resizeEvent( QResizeEvent* event )
{
QAbstractButton::resizeEvent( event );
_offset = _endOffset.value(isChecked() );
}
void SWToggleSwitch::mouseReleaseEvent( QMouseEvent* event )
{
QAbstractButton::mouseReleaseEvent( event );
if( event->button() == Qt::LeftButton)
{
_animation->setDuration(120);
_animation->setPropertyName("_offset");
_animation->setStartValue(_offset);
_animation->setEndValue(_endOffset[isChecked()]);
_animation->start();
}
}
void SWToggleSwitch::enterEvent( QEvent* event )
{
setCursor(Qt::PointingHandCursor);
QAbstractButton::enterEvent(event);
}
void SWToggleSwitch::setChecked( bool checked )
{
QAbstractButton::setChecked( checked );
_offset = _endOffset.value ( checked );
}
int SWToggleSwitch::offset()
{
return _offset;
}
void SWToggleSwitch::setOffset(int value)
{
_offset = value;
update();
}