330 lines
7.7 KiB
C++
330 lines
7.7 KiB
C++
/***************************************************************************
|
|
|
|
source::worx raDIYo
|
|
Copyright © 2020-2022 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.
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
/**
|
|
* contains copy-writen material from qt example code:
|
|
* @see shaped clock example
|
|
* @see embedded/flipdigits example
|
|
*
|
|
* **/
|
|
|
|
|
|
#include <QWidget>
|
|
#include <QtCore>
|
|
#include <QPainter>
|
|
#include <QFontDatabase>
|
|
#include <QColor>
|
|
#include <QPen>
|
|
|
|
#include <swflipdigit.h>
|
|
#include <raDIYoglobals.h>
|
|
|
|
|
|
SWFlipDigit::SWFlipDigit( QWidget *parent )
|
|
: QWidget( parent ),
|
|
_transition( Slide )
|
|
{
|
|
|
|
setFocusPolicy( Qt::StrongFocus );
|
|
|
|
//setAttribute( Qt::WA_OpaquePaintEvent, true );
|
|
setAttribute( Qt::WA_NoSystemBackground, true );
|
|
connect(&_animator, SIGNAL(frameChanged(int)), SLOT(update()));
|
|
_animator.setFrameRange( 0, 100 );
|
|
_animator.setDuration( 600 );
|
|
_animator.setEasingCurve( ( QEasingCurve( QEasingCurve::InOutQuad ) ) );
|
|
|
|
_fontFamily = SWDEFAULTFONT;
|
|
|
|
}
|
|
|
|
SWFlipDigit::~SWFlipDigit()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void SWFlipDigit::setTransition( FlipMode tr)
|
|
{
|
|
_transition = tr;
|
|
}
|
|
|
|
|
|
SWFlipDigit::FlipMode SWFlipDigit::transition() const
|
|
{
|
|
return _transition;
|
|
}
|
|
|
|
|
|
|
|
void SWFlipDigit::setValue( int value )
|
|
{
|
|
if( _value != value )
|
|
{
|
|
_value = qBound( _rangeFrom, value, _rangeTo );
|
|
preparePixmap();
|
|
update();
|
|
}
|
|
}
|
|
|
|
|
|
void SWFlipDigit::flipTo( int n )
|
|
{
|
|
if( _value != n )
|
|
{
|
|
_value = qBound( _rangeFrom, n, _rangeTo );
|
|
_lastPixmap = _pixmap;
|
|
preparePixmap();
|
|
_animator.stop();
|
|
_animator.start();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void SWFlipDigit::drawFrame( QPainter* painter, const QRect &rect )
|
|
{
|
|
|
|
painter->setPen(Qt::NoPen);
|
|
|
|
QLinearGradient gradient( rect.topLeft(), rect.bottomLeft() );
|
|
gradient.setColorAt(0.00, QColor(245, 245, 245) );
|
|
gradient.setColorAt(0.49, QColor(192, 192, 192) );
|
|
gradient.setColorAt(0.51, QColor(245, 245, 245) );
|
|
gradient.setColorAt(1.00, QColor(192, 192, 192) );
|
|
painter->setBrush( gradient );
|
|
|
|
QRect r = rect;
|
|
painter->drawRoundedRect( r, 15, 15, Qt::RelativeSize );
|
|
r.adjust( 1, 4, -1, -4 );
|
|
painter->setPen (QColor( 181, 181, 181 ) );
|
|
painter->setBrush( Qt::NoBrush );
|
|
painter->drawRoundedRect( r, 15, 15, Qt::RelativeSize );
|
|
painter->setPen( QColor( 159, 159, 159 ));
|
|
int y = rect.top() + rect.height() / 2 - 1;
|
|
painter->drawLine( rect.left(), y, rect.right(), y );
|
|
|
|
|
|
}
|
|
|
|
|
|
QPixmap SWFlipDigit::drawDigits( int digit, const QRect &rect )
|
|
{
|
|
|
|
QString strDigit = QString::number( digit );
|
|
if( strDigit.length() == 1 )
|
|
strDigit.prepend( '0' );
|
|
|
|
// FIX!
|
|
QFont font;
|
|
|
|
font.setFamily( _fontFamily );
|
|
|
|
int fontHeight = _scaleFactor * _fontScale * rect.height();
|
|
font.setPixelSize( fontHeight );
|
|
//font.setBold( true );
|
|
|
|
QPixmap pixmap( rect.size() * _scaleFactor );
|
|
pixmap.fill( Qt::transparent );
|
|
|
|
QLinearGradient gradient( QPoint( 0, 0 ), QPoint( 0, pixmap.height() ) );
|
|
gradient.setColorAt( 0.00, QColor(128, 128, 128) );
|
|
gradient.setColorAt( 0.49, QColor(64, 64, 64) );
|
|
gradient.setColorAt( 0.51, QColor(128, 128, 128) );
|
|
gradient.setColorAt( 1.00, QColor(16, 16, 16) );
|
|
|
|
QPainter painter;
|
|
painter.begin( &pixmap );
|
|
painter.setFont( font );
|
|
QPen pen;
|
|
pen.setBrush( QBrush( gradient ) );
|
|
painter.setPen( pen );
|
|
|
|
QRect pos = pixmap.rect();
|
|
pos.adjust( 0, -100, 0, 0 );
|
|
|
|
painter.drawText( pos, Qt::AlignCenter, strDigit );
|
|
painter.end();
|
|
|
|
return pixmap.scaledToWidth( width(), Qt::SmoothTransformation );
|
|
|
|
}
|
|
|
|
|
|
void SWFlipDigit::preparePixmap()
|
|
{
|
|
_pixmap = QPixmap( size() );
|
|
_pixmap.fill(Qt::transparent);
|
|
QPainter painter( &_pixmap );
|
|
painter.drawPixmap( 0, 0, drawDigits( _value, rect() ) );
|
|
}
|
|
|
|
|
|
void SWFlipDigit::resizeEvent( QResizeEvent* )
|
|
{
|
|
preparePixmap();
|
|
update();
|
|
}
|
|
|
|
|
|
|
|
|
|
void SWFlipDigit::paintStatic()
|
|
{
|
|
QPainter painter( this );
|
|
drawFrame( &painter, rect() );
|
|
painter.drawPixmap( 0, 0, _pixmap );
|
|
}
|
|
|
|
|
|
void SWFlipDigit::paintSlide()
|
|
{
|
|
QPainter painter( this );
|
|
painter.fillRect( rect(), Qt::black );
|
|
|
|
//int pad = SWPADWIDTH;
|
|
//QRect fr = rect().adjusted( pad, pad, -pad, -pad );
|
|
drawFrame( &painter, rect() );
|
|
painter.setClipRect( rect() );
|
|
|
|
int y = height() * _animator.currentFrame() / 100;
|
|
painter.drawPixmap( 0, y, _lastPixmap );
|
|
painter.drawPixmap( 0, y - height(), _pixmap );
|
|
}
|
|
|
|
|
|
void SWFlipDigit::paintFlip()
|
|
{
|
|
|
|
QPainter painter( this );
|
|
painter.setRenderHint( QPainter::SmoothPixmapTransform, true );
|
|
painter.setRenderHint( QPainter::Antialiasing, true );
|
|
|
|
|
|
int hw = width() / 2;
|
|
int hh = height() / 2;
|
|
|
|
// behind is the new pixmap
|
|
|
|
// int pad = SWPADWIDTH;
|
|
QRect fr = rect();//.adjusted( pad, pad, -pad, -pad );
|
|
drawFrame( &painter, fr );
|
|
painter.drawPixmap( 0, 0, _pixmap );
|
|
|
|
int index = _animator.currentFrame();
|
|
|
|
if( index <= 50 )
|
|
{
|
|
|
|
// the top part of the old pixmap is flipping
|
|
int angle = -180 * index / 100;
|
|
QTransform transform;
|
|
transform.translate(hw, hh);
|
|
transform.rotate( angle, Qt::XAxis );
|
|
painter.setTransform(transform);
|
|
drawFrame( &painter, fr.adjusted(-hw, -hh, -hw, -hh ) );
|
|
painter.drawPixmap(-hw, -hh, _lastPixmap);
|
|
|
|
// the bottom part is still the old pixmap
|
|
painter.resetTransform();
|
|
painter.setClipRect(0, hh, width(), hh);
|
|
drawFrame( &painter, fr );
|
|
painter.drawPixmap( 0, 0, _lastPixmap );
|
|
return;
|
|
}
|
|
|
|
|
|
painter.setClipRect( 0, hh, width(), hh );
|
|
|
|
// the bottom part is still the old pixmap
|
|
drawFrame( &painter, fr );
|
|
painter.drawPixmap(0, 0, _lastPixmap );
|
|
|
|
// the bottom part of the new pixmap is flipping
|
|
int angle = 180 - 180 * _animator.currentFrame() / 100;
|
|
QTransform transform;
|
|
transform.translate( hw, hh);
|
|
transform.rotate( angle, Qt::XAxis );
|
|
painter.setTransform( transform );
|
|
drawFrame( &painter, fr.adjusted( -hw, -hh, -hw, -hh ) );
|
|
painter.drawPixmap( -hw, -hh, _pixmap );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
void SWFlipDigit::paintRotate()
|
|
{
|
|
QPainter p(this);
|
|
|
|
//int pad = SWPADWIDTH;
|
|
QRect fr = rect();//.adjusted(pad, pad, -pad, -pad);
|
|
drawFrame(&p, fr);
|
|
p.setClipRect(fr);
|
|
|
|
int angle1 = -180 * _animator.currentFrame() / 100;
|
|
int angle2 = 180 - 180 * _animator.currentFrame() / 100;
|
|
int angle = ( _animator.currentFrame() <= 50 ) ? angle1 : angle2;
|
|
QPixmap pix = ( _animator.currentFrame() <= 50 ) ? _lastPixmap : _pixmap;
|
|
|
|
QTransform transform;
|
|
transform.translate( width() / 2, height() / 2 );
|
|
transform.rotate( angle, Qt::XAxis );
|
|
|
|
p.setTransform(transform);
|
|
p.setRenderHint( QPainter::SmoothPixmapTransform, true );
|
|
p.drawPixmap(-width() / 2, -height() / 2, pix);
|
|
}
|
|
|
|
|
|
void SWFlipDigit::paintEvent( QPaintEvent* )
|
|
{
|
|
QPainter painter( this );
|
|
painter.fillRect( rect(), Qt::black );
|
|
|
|
if( _animator.state() == QTimeLine::Running )
|
|
{
|
|
if(_transition == Slide )
|
|
paintSlide();
|
|
if(_transition == Flip )
|
|
paintFlip();
|
|
if(_transition == Rotate )
|
|
paintRotate();
|
|
}
|
|
else
|
|
{
|
|
paintStatic();
|
|
}
|
|
|
|
drawMark( this );
|
|
|
|
|
|
}
|
|
|
|
|
|
void SWFlipDigit::onDialDeltaChanged( int delta )
|
|
{
|
|
|
|
// gültigkeit sicherstellen
|
|
int newval = _value + delta;
|
|
newval = qBound( _rangeFrom, newval, _rangeTo );
|
|
if( _value == newval )
|
|
return;
|
|
setValue( newval );
|
|
update();
|
|
|
|
}
|
|
|