raDIYo 0.4
swradiyomainwidget.cpp
1/***************************************************************************
2
3 source::worx raDIYo
4 Copyright © 2020-2022 c.holzheuer
5 c.holzheuer@sourceworx.org
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12***************************************************************************/
13
14
15#include <QDebug>
16#include <QAction>
17#include <QCoreApplication>
18#include <QMouseEvent>
19#include <QPainter>
20#include <QTime>
21#include <QTimer>
22#include <QMediaPlayer>
23#include <QUrl>
24#include <QFileInfo>
25#include <QStyle>
26#include <QFileDialog>
27#include <QStandardPaths>
28#include <QMessageBox>
29#include <QFontDatabase>
30
31#include <QHoverEvent>
32//#include <QPointF>
33#include <algorithm> // std::swap
34
35#include <swradiyomainwidget.h>
36#include <ui_swradiyomainwidget.h>
37#include <swshutdowndialog.h>
38#include <swclockcontrol.h>
39#include <swplayercontrol.h>
40#include <swsendercontrol.h>
41#include <swsongscontrol.h>
42#include <swalarmcontrol.h>
43#include <swsetupcontrol.h>
44#include <swusbcontrol.h>
45#include <swbluetoothcontrol.h>
46
47#include <iostream>
48
49
50
51/*
52static QString formatTime( qint64 timeMilliSeconds )
53{
54 qint64 seconds = timeMilliSeconds / 1000;
55 const qint64 minutes = seconds / 60;
56 seconds -= minutes * 60;
57 return QStringLiteral("%1:%2")
58 .arg(minutes, 2, 10, QLatin1Char('0'))
59 .arg(seconds, 2, 10, QLatin1Char('0'));
60}
61*/
62
74 : SWRaDIYoBaseWidget( parent )
75{
76
77
80
82 /*
83 QAction *quitAction = new QAction(tr( "--E&xit"), this );
84 quitAction->setShortcut( tr("Ctrl+Q") );
85 connect( quitAction, &QAction::triggered, qApp, &QCoreApplication::quit );
86 addAction( quitAction );
87 setContextMenuPolicy( Qt::ActionsContextMenu );
88 setToolTip(tr("Drag the clock with the left mouse button.\n"
89 "Use the right mouse button to open a context menu."));
90 setWindowTitle( tr("source::worx raDIYo") );
91 */
92
93
97
98 _radioButtons.addKeyButton( _buttonSender, SWSENDERCONTROL, "sender" );
99 _radioButtons.addKeyButton( _buttonSongs, SWSONGSCONTROL, "songs" );
100 _radioButtons.addKeyButton( _buttonUSB, SWUSBCONTROL, "usb" );
101 //_radioButtons.addKeyButton( _buttonBlueTooth, SWBLUETOOTHCONTROL, "bluetooth" );
102
103 _radioButtons.addKeyButton( _buttonClock, SWCLOCKCONTROL, "clock" );
104 _radioButtons.addKeyButton( _buttonAlarm, SWALARMCONTROL, "alarm" );
105 _radioButtons.addKeyButton( _buttonPlay, SWPLAYERCONTROL, "play" );
106 _radioButtons.addKeyButton( _buttonSetup, SWSETUPCONTROL, "setup" );
107 _radioButtons.addKeyButton( _buttonShutdown, SWSHUTDOWNCONTROL, "shutdown" );
108
109 //connect( &_radioButtons, &QButtonGroup::idClicked, this, &SWRaDIYoMainWidget::onIDTriggered );
110 connect( &_radioButtons, &SWButtonGroup::idSelected, this, &SWRaDIYoMainWidget::onIDTriggered );
111
112 // play button hat ne sonderstellung
113 connect( _buttonPlay, &QPushButton::clicked, this, &SWRaDIYoMainWidget::onVolumeButtonClicked );
114
115
116
117#ifdef Q_OS_LINUX
118 qDebug() << " --- Q_OS_LINUX";
119#endif
120
121
122#ifdef Q_OS_WIN
123 qDebug() << " --- Q_OS_WIN";
125 setupDials();
126#endif
127
129 _senderControl = new SWSenderControl( this );
130 _songsControl = new SWSongsControl( this );
131 _playerControl = new SWPlayerControl( this );
132
133 _controls.resize( SWCONTROLSSIZE );
134 _controls[SWCLOCKCONTROL] = new SWClockControl( this );
135 _controls[SWALARMCONTROL] = new SWAlarmControl( this );
136 _controls[SWPLAYERCONTROL] = _playerControl;
137 _controls[SWSENDERCONTROL] = _senderControl;
138 _controls[SWSONGSCONTROL] = _songsControl;
139 _controls[SWSETUPCONTROL] = new SWSetupControl( this );
140 _controls[SWUSBCONTROL] = new SWUSBControl( this );
141 //_controls[SWBLUETOOTHCONTROL] = new SWBlueToothControl( this );
142
143
144 _idleTimer.setInterval( raDIYo::IdleTimeOut );
145 _idleTimer.setSingleShot( true );
146 connect( &_idleTimer, &QTimer::timeout, this, &SWRaDIYoMainWidget::onIdleTimeOut );
147
149 connect( _volumeControl, SIGNAL(valueChanged(int)), _playerControl, SLOT(onDialValueChanged(int)) );
150
152
153 // wir nehmen, falls vorhanden, den ersten song als default.
154 _songsControl->getCurrentEntry( _nowPlaying );
155 _currentTitle->setText( _nowPlaying.title );
156 _nowPlaying.volume = 40;
157 _version->setText( raDIYo::Version );
158
159 // clock ist default
160 _lastControlID = _currentCtrlID = SWCLOCKCONTROL;
161 currentControl().show();
162 _buttonClock->setChecked( true );
163
164 // hier sind wir auch für die voreinstellungen zuständig: falls
165 // nicht vorhanden, default setzen
166 if( !_settings.contains( raDIYo::KeySongsDir ) )
167 _settings.setValue( raDIYo::KeySongsDir, QDir::homePath() + raDIYo::SongsDir );
168
169 // Wir lesen die Hard-Kodierte Senderliste und schreiben sie in die
170 // settings datenbank
171 if( !_settings.contains( raDIYo::KeySenderList ) )
172 {
173 QString senderList = readResource( raDIYo::ResSenderList );
174 // oder doch lieber in ein FILE?
175 _settings.setValue( raDIYo::KeySenderList, senderList );
176 }
177 // setup list controls
178 _senderControl->loadEntryList( _settings.value( raDIYo::KeySenderList ).toString() );
179 _songsControl->loadEntryList( _settings.value( raDIYo::KeySongsDir ).toString() );
180
181 // brauchts des?
182 // einigermassen synchron halten
183 //_playerControl->setVolume( _nowPlaying.volume );
184 //_dialDialog.leftDial().dial()->setValue( _nowPlaying.volume );
185
186
187
188}
189
195{
196 _playerControl->stopPlaying();
197
198}
199
200
202{
203
204 // Prinzip: Clicks (also 'drücken' in echt) schalten weiter, drehen schaltet auch weiter
205 // wenn das control mit 'drehen' nix anfangen kann, wie z.B. das FlipClock control
206
207 /*
208 * Schaltschema bei Click:
209 * Radio aus / Uhr -click-> Radio ein
210 * Radio ein -click-> Radio aus / Uhr
211 * Radio aus / Uhr -turn-> Radio ein / VolumeDislay
212 * Radio ein -turn-> Radio ein / VolumeDislay
213 */
214
216 connect( _dialDialog.leftDial().pushButton(), &QPushButton::clicked, this, &SWRaDIYoMainWidget::onSenderButtonClicked );
217 connect( _dialDialog.leftDial().dial(), &QDial::valueChanged, this, &SWRaDIYoMainWidget::onSenderValueChanged );
218
219 connect( _dialDialog.rightDial().pushButton(), &QPushButton::clicked, this, &SWRaDIYoMainWidget::onVolumeButtonClicked );
220 connect( _dialDialog.rightDial().dial(), &QDial::valueChanged, this, &SWRaDIYoMainWidget::onVolumeValueChanged );
221
222 _dialDialog.show();
223
224
225
226}
227
228
229QSettings& SWRaDIYoMainWidget::settings()
230{
231 return _settings;
232}
233
234
237{
238 qDebug() << "--- onIdleTimeOut";
239 // swap back
240 swapControls( SWCLOCKCONTROL );
241}
242
243
244void SWRaDIYoMainWidget::swapControls( int newID )
245{
246
247 qDebug() << "Fade IN" << newID << " Fade OUT: " << _currentCtrlID;
248
249 // ausblenden
250 currentControl().fadeOut();
251 _radioButtons.button( _currentCtrlID )->setChecked( false );
252
253 // alte ID merken
254 _lastControlID = _currentCtrlID;
255
256 // einblenden
257 _currentCtrlID = newID;
258 _radioButtons.button( newID )->setChecked( true );
259 currentControl().fadeIn();
260
261}
262
263
270{
271
272 qDebug() << "onIDTriggered( int newID ): " << newID;
273
274 // nochmal auf aktuelle ID geklickt? wird als 'back'
275 // betrachtet
276
277 if( SWPLAYERCONTROL != newID && newID == _currentCtrlID )
278 return onIdleTimeOut();
279
280
281 switch( newID )
282 {
283
285 case SWPLAYERCONTROL :
286
287 qDebug("SW PLAYER CONTROL");
289
290
291
292 case SWSENDERCONTROL : case SWSONGSCONTROL : case SWUSBCONTROL :
293
294 //_idleTimer.start();
295 break;
296
297
298 case SWALARMCONTROL :
299
300 qDebug("SW ALARM CONTROL");
301 break;
302
303 case SWCLOCKCONTROL :
304
305 qDebug("SW CLOCK CONTROL");
306 break;
307
308 case SWSETUPCONTROL :
309
310 qDebug("SW SETUP CONTROL");
311 break;
312
313 case SWSHUTDOWNCONTROL :
314
315 qDebug("SW SHUTDOWN CONTROL");
316 currentControl().fadeOut();
317 //SWControlType curID = _currentCtrlID;
318 onShutDown();
319 // hierher kommen wir nur bei 'shutdown canceled',
320 // also den 'alten' Zustand wiederherstellen
321 _radioButtons.button( _currentCtrlID )->setChecked( true );
322 //return;
323
324 }
325
326 swapControls( newID );
327
328
329
330}
331
332
354{
355
356 qDebug() << "onSenderButtonClicked()";
357
358}
359
360
367{
368 qDebug() << "--onSenderValueChanged: " << value << " :" << _radioButtons.checkedId();
369
370 // Wenn das akutelle Control mit Dial-Event umgehen kann
371 // dann schicken wir sie dahin
372
373 if( currentControl().acceptDial() )
374 return currentControl().onDialValueChanged( value );
375
376 // das akutelle Control kann nix mit dem 'event' anfangen( play, clock)
377 // dann schicken wir ihn an die ButtonGroup
378
379 _radioButtons.onDialValueChanged( value );
380
381}
382
383
395{
396 //onIDTriggered( _transitionsRight[_currentCtrlID] );
397
398 qDebug("--onVolumeButtonClicked()");
399
400}
401
402
409{
410
411 //onDialValueChanged( _transitionsRight, value );
412 //_playerControl->onDialValueChanged( value );
413 double dvalue = 0;
414 if( value )
415 dvalue = (double) value / 100;
416 qDebug() << "--:onVolumeValueChanged: " << value << ": " << dvalue;
417 //_volumeControl->setValue( dvalue );
418
419}
420
421
422// ...
423void SWRaDIYoMainWidget::onEntryActivated( SWPlayableItem item )
424{
425 qDebug() << "--:onEntryActivated: " << _currentCtrlID << ":" << item.title << ": " << item.urlText;
426
427 // mehrfache ansagen ignorieren
428 if( _nowPlaying.urlText == item.urlText )
429 return;
430
431 // merken
432 _nowPlaying = item;
433 // abschalten ...
434 _playerActive = false;
435 // ... und wieder anschalten
437
438}
439
440
449{
450
451 _playerActive = !_playerActive;
452
453 //QString fullUrl = raDIYo::SngDir + urlText;
454 qDebug() << "\n\n+++ togglePlayMode(): " << _currentCtrlID << " :" << _nowPlaying.title << " Url: " << _nowPlaying.urlText << "\n\n";
455
456 //FIX!
457 //QString color = _playerActive ? "rgb(181,181,181)" : "rgb(69,69,69);";
458 //_currentTitle->setStyleSheet( _titleCss.arg( color ) );
459 _currentTitle->setText( _nowPlaying.title );
460
461 _buttonPlay->setStyleSheet( _playerActive ? _buttonPauseCss : _buttonPlayCss ) ;
462 //_buttonPlay->setStyleSheet( _buttonPauseCss ) ;
463
464 // FIX! das haut nicht hin
465 if( !_playerActive )
466 {
467 qDebug() << " --- Player OFF";
468 _playerControl->stopPlaying();
469 return swapControls( _lastControlID );
470 }
471
472 qDebug() << " --- Player ON";
473 swapControls( SWPLAYERCONTROL );
474
475
476 //_radioButtons.button( SWPLAYERCONTROL )->setChecked( true );
477 _playerControl->startPlaying( _nowPlaying.urlText );
478
479
480}
481
482
488{
489
490 qDebug() << "SWRaDIYoMainWidget::loadSettings()";
491
493 resize( RADIYO_LARGE_X, RADIYO_LARGE_Y );
494
495 qDebug() << QDir( raDIYo::FontDir ).entryList();
496 QStringList fontList = QDir( raDIYo::FontDir ).entryList();
497 for( const QString& fontName : fontList )
498 {
499 //qDebug() << "JaWat1: " << fontName;
500 QFontDatabase::addApplicationFont( raDIYo::FontDir + fontName );
501 }
502
503
504 //QFontDatabase fontDB;
505 //for(const QString& s : fontDB.families() )
506 // qDebug() << "JaWat: " << s;
507
508
509 // css kram erzeugen
510 _buttonPlayCss = readResource( SWPLAYBUTTONNSTYLE );
511 _buttonPauseCss = readResource( SWPAUSEBUTTONNSTYLE );
512 _titleCss = readResource( SWTITLELABELSTYLE );
513
514 setupUi( this );
515
516}
517
518
523{
524
525}
526
527
533{
534
535}
536
537
545{
546
547 /*
548 #ifdef Q_OS_WIN
549 prepareInput( audiobuffer, _s16s, INT_MAX );
550 #endif
551 #ifdef Q_OS_UNIX
552 prepareInput( audiobuffer, _s16s, SHRT_MAX );
553 #endif
554
555 */
556
557 SWShutDownDialog dialog;
558 if( QDialog::Rejected == dialog.exec() )
559 return;
560
561 // wir wollen sterben
562 ::exit( 0 );
563
564
565}
566
567
568
569
virtual void onDialValueChanged(int value)
Wird aufgerufen, wenn das (externe) Dial gedreht wurde.
void onDialValueChanged(int value)
von aussen
void idSelected(int newID)
Das ist identisch zu idClicked, das gibts aber im 'alten' Qt5 auf dem RasPI nicht.
void startPlaying(const QString &urlText)
SWPlayerControl::startPlaying: Erwartet eine ordentliche URL als String.
void onIDTriggered(int id)
onIDTriggered
void onShutDown()
onShutDown
void loadSettings()
loadSettings: die Einstellungen laden (fonts etc.)
void onVolumeValueChanged(int value)
onVolumeValueChanged
void onSenderValueChanged(int value)
onSenderValueChanged
void onVolumeButtonClicked()
onVolumeButtonClicked() wechselt zwischen Play- und Standby-Mode
void onSenderButtonClicked()
swapControls
void togglePlayMode()
startPlaying: von aussen und von innen
virtual ~SWRaDIYoMainWidget()
~SWRaDIYoMainWidget Destructor.
void saveSettings()
saveSettings
SWRaDIYoMainWidget(QWidget *parent=nullptr)
SWRaDIYoMainWidget –doku begins here —.