added config

This commit is contained in:
Anika Raemer 2021-09-26 21:49:21 +02:00
parent 893a2990af
commit f02f439790
7 changed files with 168 additions and 17 deletions

View file

@ -23,7 +23,7 @@ Item{
anchors.top: parent.top anchors.top: parent.top
anchors.margins: visible ? container.margins : 0 anchors.margins: visible ? container.margins : 0
visible: container.height > 500 visible: container.height > 500 && uiStateModel.pShowQuitAppButton
diameter: visible ? defaultDiameter : 0 diameter: visible ? defaultDiameter : 0
imageSource: "qrc:/icon_close" imageSource: "qrc:/icon_close"
@ -56,6 +56,7 @@ Item{
VolumeSlider{ VolumeSlider{
id: volumeSlider id: volumeSlider
visible: uiStateModel.pShowVolumeControls
anchors{ anchors{
right: parent.right right: parent.right
top: closeAppButton.bottom top: closeAppButton.bottom

View file

@ -23,6 +23,7 @@ Item {
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.margins: container.margins anchors.margins: container.margins
visible: uiStateModel.pShowQuitAppButton
imageSource: "qrc:/icon_close" imageSource: "qrc:/icon_close"
onClicked: { onClicked: {
Qt.quit(); Qt.quit();

View file

@ -31,6 +31,11 @@ void NavigationController::init(const QString &rootPath)
mNavList->setModelItems(mRootItem->getChildren()); mNavList->setModelItems(mRootItem->getChildren());
} }
void NavigationController::setUiProfile(const QString &profileString)
{
mUiState->setProfile(profileString);
}
void NavigationController::setContext(QQmlContext *context) void NavigationController::setContext(QQmlContext *context)
{ {
mContext = context; mContext = context;

View file

@ -9,19 +9,50 @@ class NavigationListModel;
class UiStateModel; class UiStateModel;
class MusicController; class MusicController;
/**
* @brief Main controller controlling ui state, navigation and music player.
*/
class NavigationController : public QObject class NavigationController : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit NavigationController(QObject *parent = nullptr); explicit NavigationController(QObject *parent = nullptr);
/**
* @brief Setup navigation model parsing all directories under rootPath
* @param rootPath path to root directory containing music
*/
void init(const QString & rootPath); void init(const QString & rootPath);
/**
* @brief Set ui profile
* @param profileString String defining profile
* @see UiStateModel::setProfile(const QString& profileString)
*/
void setUiProfile(const QString& profileString);
/**
* @brief setContext set QML Context and context properties
* @param context QmlContext
* @see setContextProperties
*/
void setContext(QQmlContext* context); void setContext(QQmlContext* context);
private: private:
/**
* @brief Register models in context
*/
void setContextProperties(); void setContextProperties();
/**
* @brief Add a directory and its subdirectories to navigation
* @param path Path to directory
* @param parentItem Parent directory
*/
void add(const QString & path, NavigationItemModel* parentItem); void add(const QString & path, NavigationItemModel* parentItem);
/**
* @brief Check whether directory contains either a subdirectory or flac or mp3 music files
* @param path path to directory
* @return true if directory is valid
*/
bool checkContent(const QString& path); bool checkContent(const QString& path);
NavigationItemModel* mRootItem; NavigationItemModel* mRootItem;
@ -35,6 +66,9 @@ private:
QQmlContext* mContext = nullptr; QQmlContext* mContext = nullptr;
private slots: private slots:
/**
* @brief Either show subdirectories or music player depending on current directory type
*/
void onNavigationRequest(); void onNavigationRequest();
}; };

View file

@ -1,34 +1,56 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include <QSettings> #include <QSettings>
#include <QCommandLineParser>
#include <QFileInfo>
#include <QDebug>
#include "controllers/NavigationController.h" #include "controllers/NavigationController.h"
#include "MouseEventSpy.h" #include "MouseEventSpy.h"
#include "EnergySaver.h" #include "EnergySaver.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
/*
* @todo Add command line parser to specify a custom config file
* https://doc.qt.io/qt-5/qcommandlineparser.html
*/
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
/* Read Settings */ /* Add command line parser to specify a custom config file
QSettings settings("me", "LenaPi"); * https://doc.qt.io/qt-5/qcommandlineparser.html
const auto rootPath = settings.value("rootPath", "/home/ar/source/lenaMusic/").toString(); // path to music files
const auto profile = settings.value("profile", "RasPiTouch").toString(); // known modes are "RasPiTouch" and "Desktop"
const auto isEnergySavingEnabled = settings.value("enableEnergySaver", true).toBool(); // enable/disable energy saver
const auto energySaverTimeout = settings.value("timeout", 60).toInt(); //timeout in seconds
const auto shutdownScript = settings.value("shutdownScript", "/usr/local/sbin/do_shutdown.sh").toString();
/* @todo Hand over profile to UiStateModel via NavigationController
* Add properties to UiStateModel for showing volume controls and close button.
* Set those properties according to profile and use them to hide/show elements in qml
*/ */
QCommandLineParser parser;
parser.setApplicationDescription("Lena's music app");
// Define a custom config file using -c or --config
QCommandLineOption configOption(QStringList() << "c" << "config", "Optional: Define custom config file");
parser.addOption(configOption);
// process commandline arguments
parser.process(app);
QSettings* settings = nullptr;
if(!parser.value(configOption).isEmpty()){
// config was handed over via commandline argument. Use this config if file exists.
QString configFilePath = parser.value(configOption);
QFileInfo configInfo(configFilePath);
if(configInfo.exists()){
settings = new QSettings(configFilePath, QSettings::Format::NativeFormat);
}
}
if(!settings){
// default config
settings = new QSettings(QSettings::Scope::UserScope, "MaleyanaSoft", "LenaPi");
}
/* Read Settings */
const auto rootPath = settings->value("rootPath", "/home/ar/source/lenaMusic/").toString(); // path to music files
const auto profile = settings->value("profile", "RasPiTouch").toString(); // known profiles are "RasPiTouch" and "Desktop"
const auto isEnergySavingEnabled = settings->value("enableEnergySaver", true).toBool(); // enable/disable energy saver
const auto energySaverTimeout = settings->value("timeout", 60).toInt(); //timeout in seconds
const auto shutdownScript = settings->value("shutdownScript", "/usr/local/sbin/do_shutdown.sh").toString();
NavigationController navController; NavigationController navController;
navController.setContext(engine.rootContext()); navController.setContext(engine.rootContext());
navController.init(rootPath); navController.init(rootPath);
navController.setUiProfile(profile);
if(isEnergySavingEnabled){ if(isEnergySavingEnabled){
/* install MouseEventSpy and energy saver used for auto shut down of device /* install MouseEventSpy and energy saver used for auto shut down of device
@ -43,6 +65,5 @@ int main(int argc, char *argv[])
// load GUI // load GUI
engine.load(QUrl("qrc:/main.qml")); engine.load(QUrl("qrc:/main.qml"));
return app.exec(); return app.exec();
} }

View file

@ -1,10 +1,30 @@
#include "UiStateModel.h" #include "UiStateModel.h"
#include <iostream>
UiStateModel::UiStateModel(QObject *parent) : QObject(parent) UiStateModel::UiStateModel(QObject *parent) : QObject(parent)
{ {
initProfiles();
showNavigation(); showNavigation();
} }
void UiStateModel::setProfile(UiStateModel::EProfile profile)
{
mProfile = profile;
emit profileChanged();
}
bool UiStateModel::isShowQuitAppButton() const
{
const auto & profileInfo = mProfileInfoMap[mProfile];
return profileInfo.isShowQuitAppButton;
}
bool UiStateModel::isShowVolumeControls() const
{
const auto & profileInfo = mProfileInfoMap[mProfile];
return profileInfo.isShowVolumeControls;
}
QUrl UiStateModel::getSource() const QUrl UiStateModel::getSource() const
{ {
return mSource; return mSource;
@ -19,3 +39,32 @@ void UiStateModel::showNavigation(){
mSource = QUrl("Navigation.qml"); mSource = QUrl("Navigation.qml");
emit sourceChanged(); emit sourceChanged();
} }
void UiStateModel::initProfiles()
{
// Profile_RasPiTouch
ProfileInfo rasPiTouchProfile;
rasPiTouchProfile.profileType = Profile_RasPiTouch;
rasPiTouchProfile.isShowQuitAppButton = false;
rasPiTouchProfile.isShowVolumeControls = false;
mProfileInfoMap.insert(rasPiTouchProfile.profileType, rasPiTouchProfile);
// Profile_Desktop
ProfileInfo desktopProfile;
desktopProfile.profileType = Profile_Desktop;
desktopProfile.isShowQuitAppButton = true;
desktopProfile.isShowVolumeControls = true;
mProfileInfoMap.insert(desktopProfile.profileType, desktopProfile);
}
UiStateModel::EProfile UiStateModel::getProfileFromString(const QString &profileString)
{
if(profileString == "Desktop"){
return Profile_Desktop;
} else if(profileString != "RasPiTouch"){
std::cout << "WARNING: Unknown profile\t" << profileString.toStdString() << std::endl;
}
return Profile_RasPiTouch;
}

View file

@ -3,6 +3,7 @@
#include <QObject> #include <QObject>
#include <QUrl> #include <QUrl>
#include <QHash>
/** /**
* @brief Handles state of UI by providing the qml source. * @brief Handles state of UI by providing the qml source.
@ -15,9 +16,12 @@ class UiStateModel : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY(QUrl pSource READ getSource NOTIFY sourceChanged) Q_PROPERTY(QUrl pSource READ getSource NOTIFY sourceChanged)
Q_PROPERTY(bool pShowQuitAppButton READ isShowQuitAppButton NOTIFY profileChanged)
Q_PROPERTY(bool pShowVolumeControls READ isShowVolumeControls NOTIFY profileChanged)
signals: signals:
void sourceChanged(); void sourceChanged();
void profileChanged();
public: public:
/** /**
@ -37,15 +41,51 @@ public:
*/ */
Profile_Desktop Profile_Desktop
}; };
explicit UiStateModel(QObject *parent = nullptr); explicit UiStateModel(QObject *parent = nullptr);
/**
* @brief setProfile
* @param profileString String identifying profile as read from config.
*
* Known profile strings are "RasPiTouch" and "Desktop".
*/
void setProfile(const QString& profileString){ setProfile(getProfileFromString(profileString)); }
void setProfile(EProfile profile);
bool isShowQuitAppButton() const;
bool isShowVolumeControls() const;
QUrl getSource() const; QUrl getSource() const;
void showMusicPlayer(); void showMusicPlayer();
void showNavigation(); void showNavigation();
private: private:
/**
* @brief Container defining ui state inforamtion for a certain profile
*/
struct ProfileInfo{
EProfile profileType = Profile_RasPiTouch;
bool isShowQuitAppButton = false;
bool isShowVolumeControls = false;
};
/**
* @brief Map containing ProfileInfo for each profile
*/
QHash<EProfile, ProfileInfo> mProfileInfoMap;
/**
* @brief Init ProfileInfo for all known profiles and init mProfileInfoMap
*/
void initProfiles();
/**
* @brief Transform given profile string to enum valie
* @param profileString String identifying profile
* @return Matching profile. If given string does not match a known profile, Profile_RasPiTouch is used as default.
*/
static EProfile getProfileFromString(const QString& profileString);
QUrl mSource; QUrl mSource;
EProfile mProfile = Profile_RasPiTouch;
}; };
#endif // UISTATEMODEL_H #endif // UISTATEMODEL_H