jamulus/src/levelmeter.cpp

247 lines
7.8 KiB
C++
Raw Normal View History

2013-01-23 11:41:13 +01:00
/******************************************************************************\
2020-01-01 15:41:43 +01:00
* Copyright (c) 2004-2020
2013-01-23 11:41:13 +01:00
*
* Author(s):
* Volker Fischer
*
* Description:
* Implements a multi color LED bar
*
******************************************************************************
*
* 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
2013-01-23 11:41:13 +01:00
*
\******************************************************************************/
2020-06-21 19:55:12 +02:00
#include "levelmeter.h"
2013-01-23 11:41:13 +01:00
/* Implementation *************************************************************/
CMultiColorLEDBar::CMultiColorLEDBar ( QWidget* parent, Qt::WindowFlags f ) :
QWidget ( parent, f ),
eLevelMeterType ( MT_BAR )
2013-01-23 11:41:13 +01:00
{
// initialize LED meter
QWidget* pLEDMeter = new QWidget();
QVBoxLayout* pLEDLayout = new QVBoxLayout ( pLEDMeter );
pLEDLayout->setAlignment ( Qt::AlignHCenter );
pLEDLayout->setMargin ( 0 );
pLEDLayout->setSpacing ( 0 );
2013-01-23 11:41:13 +01:00
// create LEDs
vecpLEDs.Init ( NUM_STEPS_LED_BAR );
for ( int iLEDIdx = NUM_STEPS_LED_BAR - 1; iLEDIdx >= 0; iLEDIdx-- )
2013-01-23 11:41:13 +01:00
{
// create LED object
vecpLEDs[iLEDIdx] = new cLED ( parent );
// add LED to layout with spacer (do not add spacer on the bottom of the first LED)
if ( iLEDIdx < NUM_STEPS_LED_BAR - 1 )
2013-01-23 11:41:13 +01:00
{
pLEDLayout->addStretch();
2013-01-23 11:41:13 +01:00
}
pLEDLayout->addWidget ( vecpLEDs[iLEDIdx]->getLabelPointer() );
2013-01-23 11:41:13 +01:00
}
// initialize bar meter
pProgressBar = new QProgressBar();
pProgressBar->setOrientation ( Qt::Vertical );
pProgressBar->setRange ( 0, 100 * NUM_STEPS_LED_BAR );
pProgressBar->setFormat ( "" ); // suppress percent numbers
// setup stacked layout for meter type switching mechanism
pStackedLayout = new QStackedLayout ( this );
pStackedLayout->addWidget ( pLEDMeter );
pStackedLayout->addWidget ( pProgressBar );
// according to QScrollArea description: "When using a scroll area to display the
// contents of a custom widget, it is important to ensure that the size hint of
// the child widget is set to a suitable value."
pProgressBar->setMinimumSize ( QSize ( 1, 1 ) );
pLEDMeter->setMinimumSize ( QSize ( 1, 1 ) );
// update the meter type (using the default value of the meter type)
SetLevelMeterType ( eLevelMeterType );
2013-01-23 11:41:13 +01:00
}
CMultiColorLEDBar::~CMultiColorLEDBar()
{
// clean up the LED objects
for ( int iLEDIdx = 0; iLEDIdx < NUM_STEPS_LED_BAR; iLEDIdx++ )
2013-01-23 11:41:13 +01:00
{
delete vecpLEDs[iLEDIdx];
}
}
void CMultiColorLEDBar::changeEvent ( QEvent* curEvent )
{
// act on enabled changed state
if ( curEvent->type() == QEvent::EnabledChange )
{
// reset all LEDs
Reset ( this->isEnabled() );
}
}
void CMultiColorLEDBar::Reset ( const bool bEnabled )
{
// update state of all LEDs
for ( int iLEDIdx = 0; iLEDIdx < NUM_STEPS_LED_BAR; iLEDIdx++ )
2013-01-23 11:41:13 +01:00
{
// different reset behavoiur for enabled and disabled control
if ( bEnabled )
{
2020-06-01 21:16:31 +02:00
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_BLACK );
2013-01-23 11:41:13 +01:00
}
else
{
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_DISABLED );
}
}
}
void CMultiColorLEDBar::SetLevelMeterType ( const ELevelMeterType eNType )
{
eLevelMeterType = eNType;
switch ( eNType )
{
case MT_LED:
pStackedLayout->setCurrentIndex ( 0 );
break;
case MT_BAR:
pStackedLayout->setCurrentIndex ( 1 );
pProgressBar->setStyleSheet (
"QProgressBar { margin: 1px;"
" padding: 1px; "
" width: 15px; }"
"QProgressBar::chunk { background: green; }" );
break;
case MT_SLIM_BAR:
// set all LEDs to disabled, otherwise we would not get our desired small width
for ( int iLEDIdx = 0; iLEDIdx < NUM_STEPS_LED_BAR; iLEDIdx++ )
{
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_DISABLED );
}
pStackedLayout->setCurrentIndex ( 1 );
pProgressBar->setStyleSheet (
"QProgressBar { border: 0px;"
" margin: 0px;"
" padding: 0px; "
" width: 4px; }"
"QProgressBar::chunk { background: green; }" );
break;
}
}
void CMultiColorLEDBar::setValue ( const double dValue )
2013-01-23 11:41:13 +01:00
{
if ( this->isEnabled() )
{
switch ( eLevelMeterType )
2013-01-23 11:41:13 +01:00
{
case MT_LED:
// update state of all LEDs for current level value
for ( int iLEDIdx = 0; iLEDIdx < NUM_STEPS_LED_BAR; iLEDIdx++ )
2013-01-23 11:41:13 +01:00
{
// set active LED color if value is above current LED index
if ( iLEDIdx < dValue )
2013-01-23 11:41:13 +01:00
{
// check which color we should use (green, yellow or red)
if ( iLEDIdx < YELLOW_BOUND_LED_BAR )
2013-01-23 11:41:13 +01:00
{
// green region
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_GREEN );
2013-01-23 11:41:13 +01:00
}
else
{
if ( iLEDIdx < RED_BOUND_LED_BAR )
{
// yellow region
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_YELLOW );
}
else
{
// red region
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_RED );
}
2013-01-23 11:41:13 +01:00
}
}
else
{
// we use grey LED for inactive state
2020-06-01 21:16:31 +02:00
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_BLACK );
}
2013-01-23 11:41:13 +01:00
}
break;
case MT_BAR:
case MT_SLIM_BAR:
pProgressBar->setValue ( 100 * dValue );
break;
2013-01-23 11:41:13 +01:00
}
}
}
CMultiColorLEDBar::cLED::cLED ( QWidget* parent ) :
BitmCubeRoundBlack ( QString::fromUtf8 ( ":/png/LEDs/res/HLEDBlackSmall.png" ) ),
BitmCubeRoundGreen ( QString::fromUtf8 ( ":/png/LEDs/res/HLEDGreenSmall.png" ) ),
BitmCubeRoundYellow ( QString::fromUtf8 ( ":/png/LEDs/res/HLEDYellowSmall.png" ) ),
BitmCubeRoundRed ( QString::fromUtf8 ( ":/png/LEDs/res/HLEDRedSmall.png" ) )
2013-01-23 11:41:13 +01:00
{
// create LED label
pLEDLabel = new QLabel ( "", parent );
// set initial bitmap
2020-06-01 21:16:31 +02:00
pLEDLabel->setPixmap ( BitmCubeRoundBlack );
eCurLightColor = RL_BLACK;
2013-01-23 11:41:13 +01:00
}
void CMultiColorLEDBar::cLED::setColor ( const ELightColor eNewColor )
{
// only update LED if color has changed
if ( eNewColor != eCurLightColor )
{
switch ( eNewColor )
{
case RL_DISABLED:
pLEDLabel->setPixmap ( QPixmap() );
2013-01-23 11:41:13 +01:00
break;
2020-06-01 21:16:31 +02:00
case RL_BLACK:
pLEDLabel->setPixmap ( BitmCubeRoundBlack );
2013-01-23 11:41:13 +01:00
break;
case RL_GREEN:
pLEDLabel->setPixmap ( BitmCubeRoundGreen );
break;
case RL_YELLOW:
pLEDLabel->setPixmap ( BitmCubeRoundYellow );
break;
case RL_RED:
pLEDLabel->setPixmap ( BitmCubeRoundRed );
break;
}
eCurLightColor = eNewColor;
}
}