Audio support W.-I.-P.; compiles; not tested yet

This commit is contained in:
Nicolas Mailloux 2023-07-24 15:15:56 -04:00
parent 1d6f307a96
commit dad0a8468d
32 changed files with 1748 additions and 79 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "libs/libsndfile"]
path = libs/libsndfile
url = https://github.com/libsndfile/libsndfile

View file

@ -25,8 +25,12 @@ DEFINES += GIT_COMMIT=\\\"$$GIT_COMMIT\\\"
SOURCES += \
src/apps/todo.cpp \
src/audio/audiothread.cpp \
src/splash/alert.cpp \
src/apps/apps.cpp \
src/widgets/dialogs/audio/audiodialog.cpp \
src/widgets/dialogs/audio/audiofile.cpp \
src/widgets/dialogs/audio/audiofilequeue.cpp \
src/widgets/dialogs/library/bookinfodialog.cpp \
src/widgets/dialogs/library/bookoptionsdialog.cpp \
src/widgets/dialogs/brightnessdialog.cpp \
@ -69,9 +73,13 @@ SOURCES += \
src/settings/powerdaemonsettings.cpp
HEADERS += \
src/audio/audiothread.h \
src/apps/todo.h \
src/splash/alert.h \
src/apps/apps.h \
src/widgets/dialogs/audio/audiodialog.h \
src/widgets/dialogs/audio/audiofile.h \
src/widgets/dialogs/audio/audiofilequeue.h \
src/widgets/dialogs/library/bookinfodialog.h \
src/widgets/dialogs/library/bookoptionsdialog.h \
src/widgets/dialogs/brightnessdialog.h \
@ -117,6 +125,9 @@ FORMS += \
src/apps/todo.ui \
src/splash/alert.ui \
src/apps/apps.ui \
src/widgets/dialogs/audio/audiodialog.ui \
src/widgets/dialogs/audio/audiofile.ui \
src/widgets/dialogs/audio/audiofilequeue.ui \
src/widgets/dialogs/library/bookinfodialog.ui \
src/widgets/dialogs/library/bookoptionsdialog.ui \
src/widgets/dialogs/brightnessdialog.ui \
@ -163,3 +174,6 @@ RESOURCES += \
src/eink.qrc
INCLUDEPATH += $$system(find ./ -type d -print -path ./.git -prune | grep -v "./.git")
INCLUDEPATH += $$PWD/libs/libsndfile/include/
DEPENDPATH += $$PWD/libs/libsndfile/include/
LIBS += -L$$PWD/libs/prebuilt -lsndfile

1
libs/libsndfile Submodule

@ -0,0 +1 @@
Subproject commit 59067eb60518fa63c8629372538075a54828328b

1
libs/prebuilt/libsndfile.so Symbolic link
View file

@ -0,0 +1 @@
libsndfile.so.1.0.35

View file

@ -0,0 +1 @@
libsndfile.so.1.0.35

Binary file not shown.

137
src/audio/audiothread.cpp Normal file
View file

@ -0,0 +1,137 @@
#include "audiothread.h"
#include "functions.h"
#include <QTimer>
// Socket things
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
#include <QTimer>
audiothread::audiothread() {}
void audiothread::start() {
log("Audio thread monitor available", className);
// QTimer doesn't work in such loops
int count = 0;
int delayMs = 100;
int secondsToCount = 1000 / delayMs;
int previousVolume = -1;
while(true) {
global::audio::audioMutex.lock();
if(count == secondsToCount) {
count = 0;
if(monitorProgress == true) {
audioProgress();
}
}
foreach(global::audio::Action action, global::audio::currentAction) {
// Order is important
if(action == global::audio::Action::Stop) {
// No need to call this before 'Play'
log("Stop action received", className);
sendInfo("pause:"); // Yea, only that
global::audio::paused = true;
global::audio::isSomethingCurrentlyPlaying = false;
global::audio::progressSeconds = -5;
monitorProgress = false;
}
if(action == global::audio::Action::Play) {
log("'Play' action received", className);
QString message = "play:\"";
QString betterPath = global::audio::queue[global::audio::itemCurrentlyPlaying].path;
betterPath.remove(0, 21); // Remove /mnt/onboard/onboard/
log("The name of the song is: '" + global::audio::queue[global::audio::itemCurrentlyPlaying].name + "'", className);
log("The path to be sent is: '" + betterPath + "'", className);
message.append(betterPath);
message.append('"');
sendInfo(message);
global::audio::paused = false;
global::audio::isSomethingCurrentlyPlaying = true;
global::audio::progressSeconds = -5;
monitorProgress = true;
}
if(action == global::audio::Action::Pause) {
log("'Pause' action received", className);
QString message = "pause:";
sendInfo(message);
global::audio::paused = true;
monitorProgress = false;
}
if(action == global::audio::Action::Continue) {
log("'Continue' action received", className);
QString message = "continue:";
sendInfo(message);
global::audio::paused = false;
monitorProgress = true;
}
}
global::audio::currentAction.clear();
if(global::audio::volumeLevel != previousVolume) {
previousVolume = global::audio::volumeLevel;
log("'Set volume' action detected", className);
QString message = "set_volume:" + QString::number(global::audio::volumeLevel);
sendInfo(message);
}
global::audio::audioMutex.unlock();
count = count + 1;
QThread::msleep(delayMs);
}
}
// I have no explanation as to why this needs to connect/disconnect every time.
// while (recv(client_sockfd, buffer_tmp, 1, 0) > 0) {
// ^ This line makes InkBox freeze
void audiothread::sendInfo(QString message) {
log("Sending message: *" + message + "*", className);
// Send
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd < 0) {
log("Error creating socket", className);
}
// Connect to the socket
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, "/dev/iaudio.socket");
res = ::connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
if (res < 0) {
log("Error connecting to socket", className);
}
log("Sending message: " + message, className);
res = send(sockfd, message.toStdString().c_str(), strlen(message.toStdString().c_str()), 0);
if (res < 0) {
log("Error sending message to socket", className);
}
log("Message sent, exiting", className);
close(sockfd);
}
// Mutex managed outside of the function
void audiothread::audioProgress() {
global::audio::progressSeconds = global::audio::progressSeconds + 1;
// log("Progress, +1 sec: " + QString::number(global::audio::progressSeconds), className);
if(global::audio::progressSeconds >= global::audio::queue[global::audio::itemCurrentlyPlaying].lengths) {
if(global::audio::itemCurrentlyPlaying >= global::audio::queue.length() - 1) {
// It's the last item
log("Last item: stopping playback", className);
global::audio::isSomethingCurrentlyPlaying = false;
global::audio::paused = true;
monitorProgress = false;
global::audio::progressSeconds = -5;
global::audio::currentAction.append(global::audio::Action::Stop);
}
else {
// It's not the last item, continuing
log("Audio file changed", className);
global::audio::itemCurrentlyPlaying = global::audio::itemCurrentlyPlaying + 1;
global::audio::currentAction.append(global::audio::Action::Play);
global::audio::songChanged = true;
}
}
}

27
src/audio/audiothread.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef AUDIOTHREAD_H
#define AUDIOTHREAD_H
#include <QObject>
#include <sys/un.h>
#include <QTimer>
class audiothread : public QObject
{
Q_OBJECT
public:
QString className = this->metaObject()->className();
audiothread();
void sendInfo(QString message);
int sockfd;
struct sockaddr_un addr;
int res;
bool monitorProgress = false;
public slots:
void start();
void audioProgress();
private:
};
#endif // AUDIOTHREAD_H

View file

@ -111,5 +111,13 @@
<file>resources/checkbox-indeterminate.png</file>
<file>resources/egg/0.jpg</file>
<file>resources/egg/1.jpg</file>
<file>resources/music-note.png</file>
<file>resources/music-library.png</file>
<file>resources/next.png</file>
<file>resources/music-queue.png</file>
<file>resources/play.png</file>
<file>resources/previous.png</file>
<file>resources/pause.png</file>
<file>resources/clean.png</file>
</qresource>
</RCC>

View file

@ -21,6 +21,7 @@
#include <QJsonArray>
#include <QCryptographicHash>
#include <QNetworkInterface>
#include <QMutex>
#include <stdio.h>
#include <fcntl.h>
@ -87,6 +88,7 @@ namespace global {
namespace text {
inline bool textBrowserDialog;
inline QString textBrowserContents;
inline QString textBrowserTitle = ""; // At default: empty; "Information" will be displayed
}
namespace keyboard {
inline bool keyboardDialog;
@ -196,6 +198,37 @@ namespace global {
int signal;
};
}
namespace audio {
inline bool enabled = false;
struct musicFile {
QString path;
QString name; // Cut path for easier use in names
int lengths; // length Seconds
QString length; // In minutes:seconds
int id;
};
// 'None' is when 'currentAction' is empty
enum class Action { // Function will be called with this enum
Play,
Next,
Previous,
Pause,
Continue,
Stop, // Sets 'paused' to false, 'isSomethingCurrentlyPlaying' to false, and 'itemCurrentlyPlaying' to -1; also stops playing
SetVolume,
};
inline QVector<Action> currentAction;
inline QVector<musicFile> queue;
inline QVector<musicFile> fileList;
inline int itemCurrentlyPlaying = -1; // Also indicates in the queue menu which a grey color which is playing
inline QMutex audioMutex; // These variables will be shared between threads, so here, it's to protect it
inline int progressSeconds = -5; // -5 at default to avoid cutting song too early... yea
inline bool paused = false;
inline bool isSomethingCurrentlyPlaying = false; // Pause and continue
inline bool firstScan = true;
inline int volumeLevel = 40; // Default save value
inline bool songChanged = false;
}
inline QString systemInfoText;
inline bool forbidOpenSearchDialog;
inline bool isN705 = false;
@ -261,9 +294,8 @@ namespace {
config.open(QIODevice::ReadOnly);
QTextStream in (&config);
const QString content = in.readAll();
std::string contentstr = content.toStdString();
config.close();
if(contentstr.find("true") != std::string::npos) {
if(content.contains("true")) {
return true;
}
else {
@ -271,6 +303,7 @@ namespace {
}
}
else {
QString function = __func__; log(function + ": Warning: File '" + file + "' doesn't exist, returning false", "functions");
return false;
}
return 0;
@ -1143,6 +1176,19 @@ namespace {
// This can cause problems if someone names their directory with HTML tags, so stop here. Anki, which is a big project, also doesn't care about this
return text.remove(QRegExp("<[^>]*>"));
}
void bool_writeconfig(QString file, bool option) {
QString str;
if(option == true) {
str = "true";
}
else {
str = "false";
}
std::ofstream fhandler;
fhandler.open(file.toStdString());
fhandler << str.toStdString();
fhandler.close();
}
}
#endif // FUNCTIONS_H

View file

@ -5,6 +5,8 @@
#include "apps.h"
#include "ui_apps.h"
#include "functions.h"
#include "audiodialog.h"
#include <QTime>
#include <QDateTime>
#include <QTimer>
@ -28,6 +30,13 @@ MainWindow::MainWindow(QWidget *parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Needed, the screen is shifted?
// ~Szybet
if(global::deviceID == "n306\n") {
ui->centralwidget->layout()->setContentsMargins(4, 5, 8, 8);
}
ui->inkboxLabel->setFont(QFont("u001"));
ui->settingsBtn->setProperty("type", "borderless");
@ -39,6 +48,7 @@ MainWindow::MainWindow(QWidget *parent)
ui->brightnessBtn->setProperty("type", "borderless");
ui->homeBtn->setProperty("type", "borderless");
ui->wifiBtn->setProperty("type", "borderless");
ui->audioBtn->setProperty("type", "borderless");
ui->settingsBtn->setText("");
ui->appsBtn->setText("");
@ -50,6 +60,7 @@ MainWindow::MainWindow(QWidget *parent)
ui->homeBtn->setText("");
ui->quoteLabel->setText("");
ui->wifiBtn->setText("");
ui->audioBtn->setText("");
ui->quotePictureLabel->setText("");
@ -132,6 +143,17 @@ MainWindow::MainWindow(QWidget *parent)
ui->brightnessBtn->setIcon(QIcon(":/resources/frontlight.png"));
ui->brightnessBtn->setIconSize(QSize(brightnessIconWidth, brightnessIconHeight));
if(global::audio::enabled == false) {
ui->audioBtn->hide();
ui->audioLine->hide();
}
else {
ui->audioBtn->setIcon(QIcon(":/resources/music-note.png"));
ui->audioBtn->setIconSize(QSize(wifiIconWidth, wifiIconHeight));
ui->labelLine_1->hide();
ui->labelLine_2->hide();
}
updateWifiAble();
if(global::device::isWifiAble == true) {
// Start Wi-Fi icon updater
@ -1055,3 +1077,9 @@ void MainWindow::setupHomePageWidget() {
ui->homeStackedWidget->setCurrentIndex(2);
global::mainwindow::tabSwitcher::homePageWidgetCreated = true;
}
void MainWindow::on_audioBtn_clicked()
{
QDialog* newAudioDialog = new audioDialog(this);
newAudioDialog->exec();
}

View file

@ -102,6 +102,7 @@ private slots:
void setupLocalLibraryWidget();
void setupHomePageWidget();
void launchOnlineLibrary();
void on_audioBtn_clicked();
private:
Ui::MainWindow * ui;

View file

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>706</width>
<width>749</width>
<height>601</height>
</rect>
</property>
@ -17,6 +17,37 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="14">
<widget class="Line" name="line_9">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="labelLine_2">
<property name="text">
<string>―</string>
</property>
</widget>
</item>
<item row="0" column="15">
<widget class="QLabel" name="batteryIcon">
<property name="text">
<string>batteryIcon</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="homeBtn">
<property name="text">
<string>Home</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
@ -30,23 +61,15 @@
</property>
</spacer>
</item>
<item row="0" column="15">
<widget class="QLabel" name="batteryLabel">
<property name="font">
<font>
<family>Inter</family>
<pointsize>11</pointsize>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<item row="0" column="9">
<widget class="QPushButton" name="brightnessBtn">
<property name="text">
<string>batt</string>
<string>Brightness</string>
</property>
</widget>
</item>
<item row="0" column="16">
<widget class="Line" name="line_8">
<item row="0" column="11">
<widget class="Line" name="line_7">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
@ -55,10 +78,13 @@
</property>
</widget>
</item>
<item row="0" column="14">
<widget class="QLabel" name="batteryIcon">
<property name="text">
<string>batteryIcon</string>
<item row="0" column="7">
<widget class="Line" name="audioLine">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
@ -75,14 +101,60 @@
</property>
</spacer>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_2">
<item row="0" column="18">
<widget class="QLabel" name="timeLabel">
<property name="font">
<font>
<family>Inter</family>
<pointsize>11</pointsize>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>time</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="17">
<widget class="Line" name="line_8">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelLine_1">
<property name="text">
<string>―</string>
</property>
</widget>
</item>
<item row="0" column="12">
<item row="0" column="16">
<widget class="QLabel" name="batteryLabel">
<property name="font">
<font>
<family>Inter</family>
<pointsize>11</pointsize>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>time</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="13">
<widget class="QPushButton" name="wifiBtn">
<property name="text">
<string>Wi-Fi</string>
@ -107,62 +179,10 @@
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label">
<item row="0" column="6">
<widget class="QPushButton" name="audioBtn">
<property name="text">
<string>―</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="homeBtn">
<property name="text">
<string>Home</string>
</property>
</widget>
</item>
<item row="0" column="17">
<widget class="QLabel" name="timeLabel">
<property name="font">
<font>
<family>Inter</family>
<pointsize>11</pointsize>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>time</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="QPushButton" name="brightnessBtn">
<property name="text">
<string>Brightness</string>
</property>
</widget>
</item>
<item row="0" column="10">
<widget class="Line" name="line_7">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="13">
<widget class="Line" name="line_9">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
<string>Audio</string>
</property>
</widget>
</item>

View file

@ -23,6 +23,7 @@
#include "encryptionmanager.h"
#include "sleepthread.h"
#include "sleepdialog.h"
#include "audiothread.h"
#include <QApplication>
#include <QFile>
@ -103,6 +104,20 @@ int main(int argc, char *argv[])
QObject::connect(sleepThreadWindow, &sleepThread::stopDialog, sleepDialogWindow, &sleepDialog::hideSleepDialog);
IPDThread->start();
// Audio stuff
if(checkconfig(".config/e-2-audio/enabled") == true) {
log("Audio is enabled", "main");
global::audio::enabled = true;
QThread * audioThread = new QThread();
audiothread * audioObject = new audiothread();
audioObject->moveToThread(audioThread);
QObject::connect(audioThread, &QThread::started, audioObject, &audiothread::start);
audioThread->start();
}
else {
log("Audio is disabled", "main");
}
if(checkconfig(".config/18-encrypted_storage/status") == true and checkconfig("/external_root/run/encfs_mounted") == false) {
// Open Encryption Manager to unlock encrypted storage
encryptionManager w;

BIN
src/resources/clean.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
src/resources/next.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
src/resources/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/resources/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/resources/previous.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -0,0 +1,450 @@
#include "audiodialog.h"
#include "ui_audiodialog.h"
#include "functions.h"
#include "audiofile.h"
#include "audiofilequeue.h"
#include <sndfile.h>
#include <unistd.h>
#include <math.h>
#include <QScreen>
audioDialog::audioDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::audioDialog)
{
ui->setupUi(this);
audioDialog::setFont(QFont("u001"));
progress = new QTimer(this);
// Size
QRect screenGeometry = QGuiApplication::screens()[0]->geometry();
this->setFixedWidth(screenGeometry.width() / 1.1);
int halfOfHalfHeight = ((screenGeometry.height() / 2) / 2) / 2;
int finalHeight = screenGeometry.height() - halfOfHalfHeight;
this->setFixedHeight(finalHeight);
// Centering dialog
int x = (screenGeometry.width() - this->width()) / 2;
int y = (screenGeometry.height() - this->height()) / 2;
this->move(x, y);
ui->minusBtn->setProperty("type", "borderless");
ui->plusBtn->setProperty("type", "borderless");
ui->exitBtn->setProperty("type", "borderless");
ui->nextBtn->setProperty("type", "borderless");
ui->previousBtn->setProperty("type", "borderless");
ui->playBtn->setProperty("type", "borderless");
ui->libraryBtn->setProperty("type", "borderless");
ui->queueBtn->setProperty("type", "borderless");
ui->refreshBtn->setProperty("type", "borderless");
int topButtonsSize = 55;
int menuButtonsSize = 80;
int playButtonsSize = 50;
ui->minusBtn->setIconSize(QSize{topButtonsSize,topButtonsSize});
ui->plusBtn->setIconSize(QSize{topButtonsSize,topButtonsSize});
ui->exitBtn->setIconSize(QSize{topButtonsSize,topButtonsSize});
ui->refreshBtn->setIconSize(QSize{topButtonsSize,topButtonsSize});
ui->nextBtn->setIconSize(QSize{playButtonsSize,playButtonsSize});
ui->previousBtn->setIconSize(QSize{playButtonsSize,playButtonsSize});
ui->playBtn->setIconSize(QSize{playButtonsSize,playButtonsSize});
ui->libraryBtn->setIconSize(QSize{menuButtonsSize,menuButtonsSize});
ui->queueBtn->setIconSize(QSize{menuButtonsSize,menuButtonsSize});
ui->fileNameLabel->setWordWrap(true);
// Default "page"
ui->libraryBtn->setStyleSheet("background: grey;");
ui->refreshBtn->setIcon(QIcon(":/resources/refresh-small.png"));
ui->refreshBtn->hide();
ui->lineRefresh->hide();
if(global::audio::firstScan == true) {
global::audio::firstScan = false;
refreshFileList();
log("Gathered files list", className);
}
refreshAudioFileWidgets();
progressFuncManage();
ui->progressSlider->setDisabled(true);
int autoRepeatDelay = 400;
int autoRepeatInterval = 20;
ui->plusBtn->setAutoRepeat(true);
ui->plusBtn->setAutoRepeatDelay(autoRepeatDelay);
ui->plusBtn->setAutoRepeatInterval(autoRepeatInterval);
ui->minusBtn->setAutoRepeat(true);
ui->minusBtn->setAutoRepeatDelay(autoRepeatDelay);
ui->minusBtn->setAutoRepeatInterval(autoRepeatInterval);
global::audio::audioMutex.lock();
ui->soundLevelSlider->setValue(global::audio::volumeLevel);
if(global::audio::isSomethingCurrentlyPlaying == true) {
ui->playBtn->setIcon(QIcon(":/resources/pause.png"));
}
global::audio::audioMutex.unlock();
finishedStartingUp = true;
}
audioDialog::~audioDialog()
{
delete ui;
}
void audioDialog::changeMenu() {
log("Menu change requested", className);
if(currentMenu != Queue) {
currentMenu = Queue;
emit deleteItself();
ui->refreshBtn->show();
ui->lineRefresh->show();
ui->refreshBtn->setIcon(QIcon(":/resources/clean.png"));
ui->libraryBtn->setStyleSheet("background: white;");
ui->queueBtn->setStyleSheet("background: grey;");
refreshAudioFileWidgetsQueue();
}
else if(currentMenu != Library){
currentMenu = Library;
emit deleteItself();
ui->refreshBtn->hide();
ui->lineRefresh->hide();
ui->libraryBtn->setStyleSheet("background: grey;");
ui->queueBtn->setStyleSheet("background: white;");
refreshAudioFileWidgets();
}
ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->minimum());
}
void audioDialog::on_libraryBtn_clicked()
{
if(currentMenu != Library) {
changeMenu();
}
}
void audioDialog::on_queueBtn_clicked()
{
if(currentMenu != Queue) {
changeMenu();
}
}
// Only on launching dialog
void audioDialog::refreshFileList() {
log("Refreshing file list", className);
if(QFile(".config/e-2-audio/path").exists() == false) {
writeFile(".config/e-2-audio/path", "/mnt/onboard/onboard/music/");
log("Music config file doesn't exist, creating it", className);
}
// For example in this path: /mnt/onboard/onboard/music/ ( with / at the end )
QString path = readFile(".config/e-2-audio/path").replace("\n", "");
log("Path for audio files: " + path, className);
QDir dir{path};
// Other file formats could be added, by building more libraries
// https://github.com/arnavyc/sndfile-alsa-example/blob/main/src/sndfile-alsa.c
// https://github.com/libsndfile/libsndfile
// Is it easy to do? Yes. Does it take more space? Yes. Do I care? No, i have this fancy command:
// for i in *; do ffmpeg -i "$i" "${i%.*}.wav"; done
// (Szybet)
dir.setNameFilters(QStringList("*.wav"));
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);
QStringList fileList = dir.entryList();
log("Files count: " + QString::number(fileList.count()), className);
global::audio::audioMutex.lock();
for (int i = 0; i < fileList.count(); i++)
{
log("Audio file: " + fileList[i], className);
global::audio::musicFile newMusicFile;
newMusicFile.path = path + fileList[i];
log("File name path: " + newMusicFile.path, className);
QString tempName = fileList[i];
tempName.chop(4); // File extension
newMusicFile.name = tempName;
log("File name length: " + QString::number(fileList[i].length()), className);
log("File name: " + tempName, className);
// http://libsndfile.github.io/libsndfile/api#open_fd
/*
sf_count_t frames ;
int samplerate ;
int channels ;
int format ;
int sections ;
int seekable ;
*/
SF_INFO sfinfo;
SNDFILE *wavFile = ::sf_open(newMusicFile.path.toStdString().c_str(), SFM_READ, &sfinfo);
// http://soundfile.sapp.org/doc/WaveFormat/
// https://stackoverflow.com/questions/53338925/get-the-audio-duration-using-libsndfile
int bareSeconds = static_cast<double>(sfinfo.frames) / (sfinfo.samplerate);
sf_close(wavFile);
newMusicFile.lengths = bareSeconds;
int countMin = 0;
while(bareSeconds >= 60) {
countMin = countMin + 1;
bareSeconds = bareSeconds - 60;
}
QString min = QString::number(countMin);
if(min.length() < 2) {
min = '0' + min;
}
QString sec = QString::number(bareSeconds);
if(sec.length() < 2) {
sec = '0' + sec;
}
newMusicFile.length = min + ":" + sec;
// To avoid shifting the line
while(newMusicFile.length.length() < 4) {
newMusicFile.length = newMusicFile.length + " ";
}
log("File length: " + newMusicFile.length, className);
newMusicFile.id = i;
global::audio::fileList.append(newMusicFile);
}
global::audio::audioMutex.unlock();
this->adjustSize();
}
void audioDialog::refreshAudioFileWidgets() {
global::audio::audioMutex.lock();
emit deleteItself();
// Doesn't work, freezes the app...
// QCoreApplication::processEvents();
for(int i = 0; i < global::audio::fileList.size(); i++) {
log("Adding new item number: " + QString::number(i), className);
audiofile* newAudioFile = new audiofile(this);
newAudioFile->provideData(global::audio::fileList[i]);
QObject::connect(this, &audioDialog::deleteItself, newAudioFile, &audiofile::die);
QObject::connect(newAudioFile, &audiofile::playFileChild, this, &audioDialog::playFile);
ui->verticalLayout->addWidget(newAudioFile, Qt::AlignTop);
}
global::audio::audioMutex.unlock();
this->adjustSize();
}
void audioDialog::refreshAudioFileWidgetsQueue() {
global::audio::audioMutex.lock();
emit deleteItself();
// Doesn't work, freezes the app...
// QCoreApplication::processEvents();
log("global::audio::itemCurrentlyPlaying: " + QString::number(global::audio::itemCurrentlyPlaying), className);
log("global::audio::isSomethingCurrentlyPlaying: " + QString::number(global::audio::isSomethingCurrentlyPlaying), className);
for(int i = 0; i < global::audio::queue.size(); i++) {
log("Adding new item: " + QString::number(i), className);
audiofilequeue* newAudioFileQueue = new audiofilequeue(this);
bool grey = false;
if(global::audio::isSomethingCurrentlyPlaying == true && global::audio::itemCurrentlyPlaying == i) {
grey = true;
}
global::audio::queue[i].id = i; // Give them invidual ID once more, because files can repeat
newAudioFileQueue->provideData(global::audio::queue[i], grey);
QObject::connect(this, &audioDialog::deleteItself, newAudioFileQueue, &audiofilequeue::die);
QObject::connect(newAudioFileQueue, &audiofilequeue::playFileChild, this, &audioDialog::playFile);
ui->verticalLayout->addWidget(newAudioFileQueue, Qt::AlignTop);
}
global::audio::audioMutex.unlock();
}
void audioDialog::on_refreshBtn_clicked()
{
global::audio::audioMutex.lock();
global::audio::currentAction.append(global::audio::Action::Stop);
global::audio::isSomethingCurrentlyPlaying = false;
global::audio::queue.clear();
global::audio::audioMutex.unlock();
refreshAudioFileWidgetsQueue();
}
void audioDialog::playFile(int itemInQueue) {
log("Called playFile", className);
log("Calling stop to current actions to play a new file", className);
global::audio::audioMutex.lock();
// All those variables will be changed in audio thread too - but too late for progressFuncManage
global::audio::itemCurrentlyPlaying = itemInQueue;
global::audio::isSomethingCurrentlyPlaying = true;
global::audio::paused = false;
global::audio::songChanged = true;
global::audio::currentAction.append(global::audio::Action::Play);
global::audio::audioMutex.unlock();
progress->stop();
progressFuncManage();
ui->playBtn->setIcon(QIcon(":/resources/pause.png"));
if(currentMenu == Queue) {
refreshAudioFileWidgetsQueue();
}
}
void audioDialog::progressFuncManage() {
global::audio::audioMutex.lock();
// log("Called progress watcher", className);
bool requestWatcher = false;
bool requestQueueRefresh = false;
if(global::audio::isSomethingCurrentlyPlaying == true) {
if(ui->progressSlider->maximum() != global::audio::queue[global::audio::itemCurrentlyPlaying].lengths) {
ui->progressSlider->setMaximum(global::audio::queue[global::audio::itemCurrentlyPlaying].lengths);
}
// log("Changing slider position: " + QString::number(global::audio::progressSeconds), className);
ui->progressSlider->setSliderPosition(global::audio::progressSeconds);
if(global::audio::songChanged == true || finishedStartingUp == false) {
log("global::audio::queue.size(): " + QString::number(global::audio::queue.size()), className);
log("global::audio::itemCurrentlyPlaying: " + QString::number(global::audio::itemCurrentlyPlaying), className);
log("Setting song name...", className);
QString currentName = global::audio::queue[global::audio::itemCurrentlyPlaying].name;
// log("New name: " + currentName, className);
ui->fileNameLabel->setText(currentName);
if(currentMenu == Queue) {
requestQueueRefresh = true;
}
global::audio::songChanged = false;
}
if(global::audio::paused == false) {
requestWatcher = true;
}
}
else {
ui->progressSlider->setSliderPosition(0);
ui->playBtn->setIcon(QIcon(":/resources/play.png"));
ui->fileNameLabel->setText("...");
if(currentMenu == Queue) {
requestQueueRefresh = true;
}
// log("Exiting progress watcher", className);
}
global::audio::audioMutex.unlock();
if(requestQueueRefresh == true) {
refreshAudioFileWidgetsQueue();
}
if(requestWatcher == true) {
// log("Launching another watcher...", className);
progress->singleShot(450, this, SLOT(progressFuncManage())); // For better accuracy, set 50
}
}
void audioDialog::on_progressSlider_sliderPressed()
{
ui->progressSlider->releaseMouse();
}
void audioDialog::on_soundLevelSlider_valueChanged(int value)
{
log("Setting volume level: " + QString::number(value), className);
// It detects if volume changes
if(finishedStartingUp == true) {
global::audio::audioMutex.lock();
global::audio::volumeLevel = value;
global::audio::audioMutex.unlock();
}
}
void audioDialog::on_plusBtn_clicked()
{
ui->soundLevelSlider->setValue(ui->soundLevelSlider->value() + 1);
}
void audioDialog::on_minusBtn_clicked()
{
ui->soundLevelSlider->setValue(ui->soundLevelSlider->value() - 1);
}
void audioDialog::on_playBtn_clicked()
{
global::audio::audioMutex.lock();
if(global::audio::isSomethingCurrentlyPlaying == true) {
if(global::audio::paused == false) {
global::audio::paused = true;
global::audio::currentAction.append(global::audio::Action::Pause);
ui->playBtn->setIcon(QIcon(":/resources/play.png"));
}
else {
global::audio::paused = false;
global::audio::currentAction.append(global::audio::Action::Continue);
ui->playBtn->setIcon(QIcon(":/resources/pause.png"));
global::audio::audioMutex.unlock();
progressFuncManage();
return void();
}
}
else if(global::audio::queue.size() - 1 >= global::audio::itemCurrentlyPlaying && global::audio::itemCurrentlyPlaying > 0) {
int tmpInt = global::audio::itemCurrentlyPlaying;
global::audio::audioMutex.unlock();
playFile(tmpInt);
ui->playBtn->setIcon(QIcon(":/resources/pause.png"));
return void();
}
else {
ui->playBtn->setIcon(QIcon(":/resources/stop.png"));
}
global::audio::audioMutex.unlock();
}
void audioDialog::on_previousBtn_clicked()
{
global::audio::audioMutex.lock();
int item = global::audio::itemCurrentlyPlaying;
item = item - 1;
if(item >= 0 && global::audio::queue.size() >= 1) {
global::audio::audioMutex.unlock();
playFile(item);
ui->previousBtn->setIcon(QIcon(":/resources/previous.png"));
ui->nextBtn->setIcon(QIcon(":/resources/next.png"));
return void();
} else {
ui->previousBtn->setIcon(QIcon(":/resources/stop.png"));
}
global::audio::audioMutex.unlock();
}
void audioDialog::on_nextBtn_clicked()
{
global::audio::audioMutex.lock();
int item = global::audio::itemCurrentlyPlaying;
item = item + 1;
if(item >= 0 && item < global::audio::queue.size()) {
global::audio::audioMutex.unlock();
playFile(item);
ui->previousBtn->setIcon(QIcon(":/resources/previous.png"));
ui->nextBtn->setIcon(QIcon(":/resources/next.png"));
return void();
} else {
ui->nextBtn->setIcon(QIcon(":/resources/stop.png"));
}
global::audio::audioMutex.unlock();
}
void audioDialog::on_exitBtn_clicked()
{
progress->stop();
progress->deleteLater();
// Make sure the mutex is unlocked
global::audio::audioMutex.tryLock();
global::audio::audioMutex.unlock();
this->deleteLater();
this->close();
}

View file

@ -0,0 +1,57 @@
#ifndef AUDIODIALOG_H
#define AUDIODIALOG_H
#include <QDialog>
#include <QTimer>
namespace Ui {
class audioDialog;
}
class audioDialog : public QDialog
{
Q_OBJECT
public:
explicit audioDialog(QWidget *parent = nullptr);
~audioDialog();
QString className = this->metaObject()->className();
enum audioMenu {
Library,
Queue,
};
bool currentMenu = Library;
void changeMenu();
void refreshFileList();
void refreshAudioFileWidgets();
void refreshAudioFileWidgetsQueue();
QTimer* progress; // Needs to be stopped at exit
bool finishedStartingUp = false;
public slots:
void playFile(int itemInQueue); // Can be called from children
void progressFuncManage();
private slots:
void on_libraryBtn_clicked();
void on_queueBtn_clicked();
void on_refreshBtn_clicked();
void on_progressSlider_sliderPressed();
void on_soundLevelSlider_valueChanged(int value);
void on_plusBtn_clicked();
void on_minusBtn_clicked();
void on_playBtn_clicked();
void on_previousBtn_clicked();
void on_nextBtn_clicked();
void on_exitBtn_clicked();
signals:
void deleteItself();
private:
Ui::audioDialog *ui;
};
#endif // AUDIODIALOG_H

View file

@ -0,0 +1,384 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>audioDialog</class>
<widget class="QDialog" name="audioDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>603</width>
<height>489</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="lineWidth">
<number>2</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="previousBtn">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/previous.png</normaloff>:/resources/previous.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="playBtn">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/stop.png</normaloff>:/resources/stop.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="nextBtn">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/next.png</normaloff>:/resources/next.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="fileNameLabel">
<property name="text">
<string>...</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="progressSlider">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="libraryBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/music-library.png</normaloff>:/resources/music-library.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="queueBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/music-queue.png</normaloff>:/resources/music-queue.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>585</width>
<height>301</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="topMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0">
<widget class="Line" name="line_4">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QPushButton" name="minusBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/minus.png</normaloff>:/resources/minus.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QScrollBar" name="soundLevelSlider">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="sliderPosition">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="plusBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/plus.png</normaloff>:/resources/plus.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="lineRefresh">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="refreshBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/refresh-small.png</normaloff>:/resources/refresh-small.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="line_2">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="exitBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/close.png</normaloff>:/resources/close.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../../../eink.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -0,0 +1,57 @@
#include "audiofile.h"
#include "ui_audiofile.h"
#include "functions.h"
audiofile::audiofile(QWidget *parent) :
QWidget(parent),
ui(new Ui::audiofile)
{
ui->setupUi(this);
audiofile::setFont(QFont("u001"));
ui->nameLabel->setWordWrap(true);
}
audiofile::~audiofile()
{
delete ui;
}
void audiofile::provideData(global::audio::musicFile fileProvided) {
file = fileProvided;
ui->nameLabel->setText(file.name);
ui->timeLabel->setText(file.length);
}
void audiofile::die() {
this->deleteLater();
this->close();
}
void audiofile::on_addBtn_clicked()
{
ui->addBtn->setDisabled(true);
ui->addBtn->setStyleSheet("background: black;");
log("Adding item (audio file) to queue", className);
global::audio::audioMutex.lock();
global::audio::queue.append(file);
if(global::audio::isSomethingCurrentlyPlaying == false) {
log("Starting playback because nothing else is currently playing", className);
global::audio::isSomethingCurrentlyPlaying = true;
int tmpInt = global::audio::queue.length() - 1;
global::audio::audioMutex.unlock();
QTimer::singleShot(700, this, SLOT(enableButton()));
emit playFileChild(tmpInt);
return void();
}
global::audio::audioMutex.unlock();
QTimer::singleShot(700, this, SLOT(enableButton()));
}
void audiofile::enableButton() {
log("Enabling 'Back' button", className);
ui->addBtn->setEnabled(true);
ui->addBtn->setStyleSheet("background: white;");
ui->addBtn->repaint();
}

View file

@ -0,0 +1,38 @@
#ifndef AUDIOFILE_H
#define AUDIOFILE_H
#include "functions.h"
#include <QWidget>
namespace Ui {
class audiofile;
}
class audiofile : public QWidget
{
Q_OBJECT
public:
explicit audiofile(QWidget *parent = nullptr);
~audiofile();
QString className = this->metaObject()->className();
void provideData(global::audio::musicFile fileProvided);
global::audio::musicFile file;
public slots:
void die();
void enableButton();
private slots:
void on_addBtn_clicked();
signals:
void playFileChild(int itemInQueue);
private:
Ui::audiofile *ui;
};
#endif // AUDIOFILE_H

View file

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>audiofile</class>
<widget class="QWidget" name="audiofile">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>316</width>
<height>53</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="nameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="timeLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/plus.png</normaloff>:/resources/plus.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../../eink.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -0,0 +1,84 @@
#include "audiofilequeue.h"
#include "ui_audiofilequeue.h"
audiofilequeue::audiofilequeue(QWidget *parent) :
QWidget(parent),
ui(new Ui::audiofilequeue)
{
ui->setupUi(this);
audiofilequeue::setFont(QFont("u001"));
ui->nameLabel->setWordWrap(true);
}
audiofilequeue::~audiofilequeue()
{
delete ui;
}
void audiofilequeue::provideData(global::audio::musicFile fileProvided, bool grey) {
file = fileProvided;
ui->nameLabel->setText(file.name);
ui->timeLabel->setText(file.length);
if(grey == true) {
log("Setting background grey", className);
ui->deleteBtn->setStyleSheet("background: grey;");
ui->playButton->setStyleSheet("background: grey;");
isPlaying = true;
}
}
void audiofilequeue::die() {
this->deleteLater();
this->close();
}
void audiofilequeue::on_deleteBtn_clicked()
{
int id = -1;
log("global::audio::queue.size(): " + QString::number(global::audio::queue.size()), className);
global::audio::audioMutex.lock();
for(int i = 0; i < global::audio::queue.size(); i++) {
if(file.id == global::audio::queue[i].id) {
log("Found ID", className);
id = i;
}
}
log("File ID is: " + QString::number(id), className);
global::audio::queue.remove(id);
// TODO: Don't change song if the removed item is not playing
// I will do it the moment I get annoyed about it
log("After removing global::audio::queue.size(): " + QString::number(global::audio::queue.size()), className);
if(id - 2 >= 0) {
global::audio::audioMutex.unlock();
emit playFileChild(id - 2);
return void();
}
else if(id < global::audio::queue.size()) {
global::audio::audioMutex.unlock();
emit playFileChild(id);
return void();
}
else {
global::audio::currentAction.append(global::audio::Action::Stop);
global::audio::audioMutex.unlock();
return void();
}
log("Something went wrong in deleting item that was in the query", className);
global::audio::audioMutex.unlock();
}
void audiofilequeue::on_playButton_clicked()
{
global::audio::audioMutex.lock();
for(int i = 0; i < global::audio::queue.size(); i++) {
if(global::audio::queue[i].id == file.id) {
global::audio::audioMutex.unlock();
emit playFileChild(i);
return void();
}
}
global::audio::audioMutex.unlock();
log("Something went really wrong", className);
}

View file

@ -0,0 +1,38 @@
#ifndef AUDIOFILEQUEUE_H
#define AUDIOFILEQUEUE_H
#include <QWidget>
#include "functions.h"
namespace Ui {
class audiofilequeue;
}
class audiofilequeue : public QWidget
{
Q_OBJECT
public:
explicit audiofilequeue(QWidget *parent = nullptr);
~audiofilequeue();
QString className = this->metaObject()->className();
bool isPlaying = false;
void provideData(global::audio::musicFile fileProvided, bool grey);
global::audio::musicFile file;
public slots:
void die();
private:
Ui::audiofilequeue *ui;
signals:
void playFileChild(int itemInQueue);
private slots:
void on_deleteBtn_clicked();
void on_playButton_clicked();
};
#endif // AUDIOFILEQUEUE_H

View file

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>audiofilequeue</class>
<widget class="QWidget" name="audiofilequeue">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>284</width>
<height>53</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="nameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="timeLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/close.png</normaloff>:/resources/close.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="playButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../eink.qrc">
<normaloff>:/resources/chevron-right.png</normaloff>:/resources/chevron-right.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>2</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../../eink.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -142,7 +142,16 @@ generalDialog::generalDialog(QWidget *parent) :
else if(global::text::textBrowserDialog == true) {
textBrowserDialog = true;
textwidgetWindow = new textwidget();
ui->headerLabel->setText("Information");
if(global::text::textBrowserTitle.isEmpty() == true) {
ui->headerLabel->setText("Information");
}
else {
ui->headerLabel->setText(global::text::textBrowserTitle);
}
// Important
ui->bodyLabel->setText(global::text::textBrowserContents);
ui->stackedWidget->setCurrentIndex(1);
ui->mainStackedWidget->insertWidget(1, textwidgetWindow);
ui->mainStackedWidget->setCurrentIndex(1);
@ -584,11 +593,13 @@ void generalDialog::on_acceptBtn_clicked()
}
if(textBrowserDialog == true) {
global::text::textBrowserContents = "";
global::text::textBrowserTitle = "";
global::text::textBrowserDialog = false;
}
if(appInfoDialog == true) {
global::text::textBrowserContents = "";
global::text::textBrowserTitle = "";
global::userApps::appInfoDialog = false;
}