first re-commit.
This commit is contained in:
442
swradiyomainwidget.cpp
Normal file
442
swradiyomainwidget.cpp
Normal file
@@ -0,0 +1,442 @@
|
||||
/***************************************************************************
|
||||
|
||||
source::worx raDIYo
|
||||
Copyright © 2020-2022 c.holzheuer
|
||||
c.holzheuer@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 <QDebug>
|
||||
#include <QAction>
|
||||
#include <QCoreApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
#include <QMediaPlayer>
|
||||
#include <QUrl>
|
||||
#include <QFileInfo>
|
||||
#include <QStyle>
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
#include <QMessageBox>
|
||||
#include <QFontDatabase>
|
||||
|
||||
//#include <QHoverEvent>
|
||||
//#include <QPointF>
|
||||
|
||||
//#include <algorithm> // std::swap
|
||||
//#include <iostream>
|
||||
|
||||
#include <swradiyomainwidget.h>
|
||||
#include <ui_swradiyomainwidget.h>
|
||||
#include <swcontrolstates.h>
|
||||
|
||||
#include <swplayercontrol.h>
|
||||
#include <swsendercontrol.h>
|
||||
#include <swsongscontrol.h>
|
||||
#include <swshutdowncontrol.h>
|
||||
#include <swclockcontrol.h>
|
||||
#include <swalarmcontrol.h>
|
||||
#include <swsetupcontrol.h>
|
||||
#include <swusbcontrol.h>
|
||||
#include <swbluetoothcontrol.h>
|
||||
|
||||
#include <SWPiGPIO.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
static QString formatTime( qint64 timeMilliSeconds )
|
||||
{
|
||||
qint64 seconds = timeMilliSeconds / 1000;
|
||||
const qint64 minutes = seconds / 60;
|
||||
seconds -= minutes * 60;
|
||||
return QStringLiteral("%1:%2")
|
||||
.arg(minutes, 2, 10, QLatin1Char('0'))
|
||||
.arg(seconds, 2, 10, QLatin1Char('0'));
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief SWRaDIYoMainWidget --doku begins here ---
|
||||
* @param parent
|
||||
*
|
||||
* contains copy-writen material from qt example code:
|
||||
* @see shaped clock example
|
||||
* @see embedded/flipdigits example
|
||||
*
|
||||
*/
|
||||
|
||||
SWRaDIYoMainWidget::SWRaDIYoMainWidget( QWidget *parent )
|
||||
: SWRaDIYoBaseWidget( parent )
|
||||
{
|
||||
|
||||
setupFonts();
|
||||
setupUi( this );
|
||||
|
||||
|
||||
/// Setup Controls: 'RaDIYo' Buttons
|
||||
/// Reihenfolge beachten, die iost wichtig für
|
||||
/// die button-asuwahl per dial
|
||||
|
||||
_controller.addButton( _buttonPlay, PlayerControl, "play" );
|
||||
_controller.addButton( _buttonSender, SenderControl, "sender" );
|
||||
_controller.addButton( _buttonSongs, SongsControl, "songs" );
|
||||
_controller.addButton( _buttonUSB, UsbControl, "usb" );
|
||||
//_controller.addButton( _buttonBlueTooth, SWBLUETOOTHCONTROL, "bluetooth" );
|
||||
|
||||
_controller.addButton( _buttonClock, ClockControl, "clock" );
|
||||
_controller.addButton( _buttonAlarm, AlarmControl, "alarm" );
|
||||
_controller.addButton( _buttonSetup, SetupControl, "setup" );
|
||||
_controller.addButton( _buttonShutdown, ShutdownControl, "shutdown" );
|
||||
|
||||
/// Alle Controls, schön vorsortiert.
|
||||
_senderControl = new SWSenderControl( this );
|
||||
_songsControl = new SWSongsControl( this );
|
||||
_playerControl = new SWPlayerControl( this );
|
||||
|
||||
|
||||
_controller.addControl( PlayerControl, _playerControl );
|
||||
_controller.addControl( SenderControl, _senderControl );
|
||||
_controller.addControl( SongsControl, _songsControl );
|
||||
_controller.addControl( UsbControl, new SWUSBControl( this ) );
|
||||
_controller.addControl( ClockControl, new SWClockControl( this ) );
|
||||
_controller.addControl( AlarmControl, new SWAlarmControl( this ) );
|
||||
_controller.addControl( SetupControl, new SWSetupControl( this ) );
|
||||
_controller.addControl( ShutdownControl, new SWShutdownControl( this ) );
|
||||
//_controller.addControl( SWBLUETOOTHCONTROL] = new SWBlueToothControl( this );
|
||||
|
||||
connect( &_raDIYoButtons, &QButtonGroup::idClicked, this, &SWControlStates::onIdActivated );
|
||||
/// play button hat ne sonderstellung
|
||||
connect( _buttonPlay, &QPushButton::clicked, this, &SWControlStates::onVolumeButtonClicked );
|
||||
|
||||
|
||||
/// Setup Controls: Fake Dials unter Win, echte für Linux
|
||||
setupDials();
|
||||
|
||||
/// startup
|
||||
loadSettings();
|
||||
|
||||
/// bei untätigkeit kommt wieder die Uhr
|
||||
_idleTimer.setInterval( raDIYo::IdleTimeOut );
|
||||
_idleTimer.setSingleShot( true );
|
||||
connect( &_idleTimer, &QTimer::timeout, this, &SWRaDIYoMainWidget::onIdleTimeOut );
|
||||
|
||||
/// Setup Controls: Volume
|
||||
connect( _volumeWidget, SIGNAL(valueChanged(int)), this, SLOT(onVolumeValueChanged(int)) );
|
||||
|
||||
|
||||
QString defSender =_settings.value( raDIYo::KeyDefaultSender ).toString();
|
||||
_nowPlaying = SWPlayableItem( defSender, SWPlayableItem::WebStream, raDIYo::DefaultVolume );
|
||||
onVolumeValueChanged( _nowPlaying.volume );
|
||||
|
||||
/// wir nehmen den default-sender
|
||||
_currentTitle->setText( _nowPlaying.title );
|
||||
|
||||
/// not least
|
||||
_version->setText( raDIYo::Version );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ~SWRaDIYoMainWidget Destructor.
|
||||
*/
|
||||
|
||||
SWRaDIYoMainWidget::~SWRaDIYoMainWidget()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SWRaDIYoMainWidget::setCurrentControl( SWAbstractControl* control )
|
||||
{
|
||||
_currentCtrl = control;
|
||||
_currentCtrl->show();
|
||||
}
|
||||
|
||||
void SWRaDIYoMainWidget::setupDials()
|
||||
{
|
||||
|
||||
/* FIX!
|
||||
* Schaltschema bei Click:
|
||||
* Radio aus / Uhr -click-> Radio ein
|
||||
* Radio ein -click-> Radio aus / Uhr
|
||||
* Radio aus / Uhr -turn-> Radio ein / VolumeDislay
|
||||
* Radio ein -turn-> Radio ein / VolumeDislay
|
||||
*/
|
||||
|
||||
|
||||
// Prinzip: Clicks (also 'drücken' in echt) schalten weiter, drehen schaltet auch weiter
|
||||
// wenn das control mit 'drehen' nix anfangen kann, wie z.B. das FlipClock control
|
||||
|
||||
//#ifdef Q_OS_LINUX
|
||||
|
||||
// Linux, kompiliert auch unter Win
|
||||
_dialLeft = new PiGPIORotaryDial( 13, 6, 5, this );
|
||||
_dialRight = new PiGPIORotaryDial( 22, 27, 17, this );
|
||||
|
||||
connect( _dialLeft, SIGNAL(clicked()), _controller, SLOT(onSenderButtonClicked()) );
|
||||
connect( _dialRight, SIGNAL(clicked()), _controller, SLOT(onVolumeButtonClicked()) );
|
||||
connect( _dialLeft, SIGNAL(valueChanged(int)), _controller, SLOT(onSenderValueChanged(int)) );
|
||||
connect( _dialRight, SIGNAL(valueChanged(int)), _volumeWidget, SLOT(onDialValueChanged(int)) );
|
||||
|
||||
//#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
qDebug() << " --- Q_OS_WIN";
|
||||
/// Setup Controls: Fake Dials
|
||||
|
||||
connect( &_dialDialog.leftDial().pushButton(), &QPushButton::clicked, _controller, &SWControlStates::onSenderButtonClicked );
|
||||
connect( &_dialDialog.leftDial().dial(), &QDial::valueChanged, _controller, &SWControlStates::onSenderValueChanged );
|
||||
connect( &_dialDialog.rightDial().pushButton(), &QPushButton::clicked, _controller, &SWControlStates::onVolumeButtonClicked );
|
||||
|
||||
connect( &_dialDialog.rightDial().dial(), &QDial::valueChanged, _volumeWidget, &SWVolumeWidget::onDialValueChanged );
|
||||
|
||||
_dialDialog.show();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
QSettings& SWRaDIYoMainWidget::settings()
|
||||
{
|
||||
return _settings;
|
||||
}
|
||||
|
||||
|
||||
/// ???
|
||||
void SWRaDIYoMainWidget::onIdleTimeOut()
|
||||
{
|
||||
qDebug() << "--- onIdleTimeOut";
|
||||
// swap back
|
||||
//swapControls( IDClockControl );
|
||||
}
|
||||
|
||||
|
||||
void SWRaDIYoMainWidget::swapControls( int newID )
|
||||
{
|
||||
|
||||
/// FIX! ButtonGroup anpassen!!!
|
||||
/*
|
||||
qDebug() << "Fade IN" << newID << " Fade OUT: " << _currentCtrlID;
|
||||
|
||||
// ausblenden
|
||||
currentControl().fadeOut();
|
||||
_raDIYoButtons.button( _currentCtrlID )->setChecked( false );
|
||||
|
||||
// alte ID merken
|
||||
_lastControlID = _currentCtrlID;
|
||||
|
||||
// einblenden
|
||||
_currentCtrlID = newID;
|
||||
_raDIYoButtons.button( newID )->setChecked( true );
|
||||
currentControl().fadeIn();
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief onIDTriggered
|
||||
* @param newID
|
||||
*/
|
||||
|
||||
void SWRaDIYoMainWidget::onIDTriggered( int newID )
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void SWRaDIYoMainWidget::onVolumeValueChanged( int value )
|
||||
{
|
||||
|
||||
/// 'setValue( value )' reicht hier nicht,
|
||||
/// denn der neue Wert muss weiter gereicht
|
||||
/// werden, also 'onDialValueChanged'
|
||||
|
||||
_volumeWidget->onDialValueChanged( value );
|
||||
_playerControl->onDialValueChanged( value );
|
||||
_dialDialog.rightDial().dial().setValue( value );
|
||||
//_dialRight.setValue( value );
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ...
|
||||
void SWRaDIYoMainWidget::onEntryActivated( SWPlayableItem item )
|
||||
{
|
||||
qDebug() << "--:onEntryActivated: " << item.title << ": " << item.urlText;
|
||||
|
||||
// Das SIGNAL kommt von einem Control, also schalten wir wieder
|
||||
// zurück auf die Buttons
|
||||
|
||||
_isCtrlActive = false;
|
||||
// mehrfache ansagen ignorieren
|
||||
if( _nowPlaying.urlText == item.urlText )
|
||||
return;
|
||||
|
||||
// merken
|
||||
_nowPlaying = item;
|
||||
// abschalten ...
|
||||
_isPlayerActive = false;
|
||||
// ... und wieder anschalten
|
||||
togglePlayMode();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief startPlaying: von aussen und von innen
|
||||
* @param title<
|
||||
* @param urlText
|
||||
* @param startnow
|
||||
*/
|
||||
|
||||
void SWRaDIYoMainWidget::togglePlayMode()
|
||||
{
|
||||
/*
|
||||
_isPlayerActive = !_isPlayerActive;
|
||||
|
||||
//QString fullUrl = raDIYo::SngDir + urlText;
|
||||
qDebug() << "\n\n+++ togglePlayMode(): " << _currentCtrlID << " :" << _nowPlaying.title << " Url: " << _nowPlaying.urlText << "\n\n";
|
||||
|
||||
//FIX!
|
||||
//QString color = _isPlayerActive ? "rgb(181,181,181)" : "rgb(69,69,69);";
|
||||
//_currentTitle->setStyleSheet( _titleCss.arg( color ) );
|
||||
_currentTitle->setText( _nowPlaying.title );
|
||||
|
||||
_buttonPlay->setStyleSheet( _isPlayerActive ? _buttonPauseCss : _buttonPlayCss ) ;
|
||||
//_buttonPlay->setStyleSheet( _buttonPauseCss ) ;
|
||||
|
||||
// FIX! das haut nicht hin
|
||||
if( !_isPlayerActive )
|
||||
{
|
||||
qDebug() << " --- Player OFF";
|
||||
_playerControl->stopPlaying();
|
||||
/// SpectrumDisplay abschalten, aber nur wenn eingeschaltet war
|
||||
if( _currentCtrlID == IDPlayerControl )
|
||||
swapControls( _lastControlID );
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << " --- Player ON";
|
||||
swapControls( IDPlayerControl );
|
||||
|
||||
_playerControl->startPlaying( _nowPlaying.urlText );
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Fonts explicit laden, _vor_ setupUi
|
||||
*/
|
||||
|
||||
void SWRaDIYoMainWidget::setupFonts()
|
||||
{
|
||||
|
||||
QStringList fontList = QDir( raDIYo::FontDir ).entryList();
|
||||
for( const QString& fontName : fontList )
|
||||
QFontDatabase::addApplicationFont( raDIYo::FontDir + fontName );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief loadSettings: die Einstellungen laden
|
||||
*/
|
||||
|
||||
void SWRaDIYoMainWidget::loadSettings()
|
||||
{
|
||||
/// Dss ist die Bildschirmgröße des Raspi 7 inch displays
|
||||
resize( SWScreenLargeX, SWScreenLargeY );
|
||||
|
||||
|
||||
/// hier sind wir auch für die voreinstellungen zuständig: falls
|
||||
/// nicht vorhanden, default setzen
|
||||
if( !_settings.contains( raDIYo::KeySongsDir ) )
|
||||
_settings.setValue( raDIYo::KeySongsDir, QDir::homePath() + raDIYo::SongsDir );
|
||||
|
||||
/// default Sender belegen
|
||||
if( !_settings.contains( raDIYo::KeyDefaultSender ) )
|
||||
_settings.setValue( raDIYo::KeyDefaultSender, raDIYo::DefaultSender );
|
||||
|
||||
/// Wir lesen die Hard-Kodierte Senderliste und schreiben sie in die
|
||||
/// settings datenbank
|
||||
if( !_settings.contains( raDIYo::KeySenderList ) )
|
||||
{
|
||||
QString senderList = readResource( raDIYo::ResSenderList );
|
||||
// oder doch lieber in ein FILE?
|
||||
_settings.setValue( raDIYo::KeySenderList, senderList );
|
||||
}
|
||||
|
||||
// setup list controls
|
||||
_senderControl->loadEntryList( _settings.value( raDIYo::KeySenderList ).toString() );
|
||||
_songsControl->loadEntryList( _settings.value( raDIYo::KeySongsDir ).toString() );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief setAlarm @todo implementation
|
||||
*/
|
||||
void SWRaDIYoMainWidget::setAlarm()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief saveSettings @todo implementation
|
||||
*/
|
||||
|
||||
void SWRaDIYoMainWidget::saveSettings()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief onShutDown
|
||||
* @todo implementation
|
||||
* @todo shutdown der hardware -> use linux 'sudo kill me'
|
||||
*/
|
||||
|
||||
void SWRaDIYoMainWidget::onShutDown()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// wir wollen sterben
|
||||
::exit( 0 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user