Add volume control
This commit is contained in:
parent
5d5e3c6888
commit
4a83f971f3
14 changed files with 144 additions and 32 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 4.8.2, 2019-08-01T21:13:48. -->
|
<!-- Written by QtCreator 4.8.2, 2021-03-13T17:07:20. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 2.4
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
Item{
|
Item{
|
||||||
|
|
@ -6,7 +7,7 @@ Item{
|
||||||
|
|
||||||
property int margins: 20
|
property int margins: 20
|
||||||
|
|
||||||
RoundButton{
|
RoundImageButton{
|
||||||
id: backNavigation
|
id: backNavigation
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -16,11 +17,15 @@ Item{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RoundButton{
|
RoundImageButton{
|
||||||
id: closeApp
|
id: closeAppButton
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.margins: container.margins
|
anchors.margins: visible ? container.margins : 0
|
||||||
|
|
||||||
|
visible: container.height > 500
|
||||||
|
diameter: visible ? defaultDiameter : 0
|
||||||
|
|
||||||
imageSource: "qrc:/icon_close"
|
imageSource: "qrc:/icon_close"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Qt.quit();
|
Qt.quit();
|
||||||
|
|
@ -49,6 +54,24 @@ Item{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VolumeSlider{
|
||||||
|
id: volumeSlider
|
||||||
|
anchors{
|
||||||
|
right: parent.right
|
||||||
|
top: closeAppButton.bottom
|
||||||
|
bottom: controlPannel.top
|
||||||
|
margins: container.margins
|
||||||
|
topMargin: closeAppButton.visible ? 2*container.margins : container.margins
|
||||||
|
}
|
||||||
|
from: 34 // we cannot hear anything if lower than 35%
|
||||||
|
to: 100
|
||||||
|
stepSize: 1
|
||||||
|
value: musicModel.pAudioVolume
|
||||||
|
onValueChanged: {
|
||||||
|
console.log(musicModel.pAudioVolume, value);
|
||||||
|
musicModel.pAudioVolume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
PlayerControlPannel {
|
PlayerControlPannel {
|
||||||
id: controlPannel
|
id: controlPannel
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import QtQuick 2.0
|
||||||
Item {
|
Item {
|
||||||
id: container
|
id: container
|
||||||
property int margins: 20
|
property int margins: 20
|
||||||
RoundButton{
|
RoundImageButton{
|
||||||
id: back
|
id: back
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -16,9 +16,9 @@ Item {
|
||||||
visible: navigationList.pIsBackVisible
|
visible: navigationList.pIsBackVisible
|
||||||
|
|
||||||
onClicked: navigationList.navigateBack();
|
onClicked: navigationList.navigateBack();
|
||||||
} // RoundButton: navigate back
|
} // MyRoundButton: navigate back
|
||||||
|
|
||||||
RoundButton{
|
RoundImageButton{
|
||||||
id: closeApp
|
id: closeApp
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -27,7 +27,7 @@ Item {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Qt.quit();
|
Qt.quit();
|
||||||
}
|
}
|
||||||
} // RoundButton: closeApp
|
} // MyRoundButton: closeApp
|
||||||
|
|
||||||
Rectangle{
|
Rectangle{
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ Item {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: container.spacing
|
spacing: container.spacing
|
||||||
|
|
||||||
RoundButton{
|
RoundImageButton{
|
||||||
id: previous
|
id: previous
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
width: 60
|
diameter: 60
|
||||||
imageSource: "qrc:/icon_previous"
|
imageSource: "qrc:/icon_previous"
|
||||||
|
|
||||||
enabled: model.pHasPrevious
|
enabled: model.pHasPrevious
|
||||||
|
|
@ -22,21 +22,21 @@ Item {
|
||||||
model.playPrevious();
|
model.playPrevious();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RoundButton{
|
RoundImageButton{
|
||||||
id: playPause
|
id: playPause
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: 80
|
diameter: 80
|
||||||
imageSource: model.pIsPlaying ? "qrc:/icon_pause" : "qrc:/icon_play"
|
imageSource: model.pIsPlaying ? "qrc:/icon_pause" : "qrc:/icon_play"
|
||||||
|
|
||||||
onClicked:{
|
onClicked:{
|
||||||
model.playPause();
|
model.playPause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RoundButton{
|
RoundImageButton{
|
||||||
id: stop
|
id: stop
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
width: 60
|
diameter: 60
|
||||||
imageSource: "qrc:/icon_stop"
|
imageSource: "qrc:/icon_stop"
|
||||||
|
|
||||||
enabled: model.pIsPlaying
|
enabled: model.pIsPlaying
|
||||||
|
|
@ -45,11 +45,11 @@ Item {
|
||||||
model.stopMusic();
|
model.stopMusic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RoundButton{
|
RoundImageButton{
|
||||||
id: next
|
id: next
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
width: 60
|
diameter: 60
|
||||||
imageSource: "qrc:/icon_next"
|
imageSource: "qrc:/icon_next"
|
||||||
|
|
||||||
enabled: model.pHasNext
|
enabled: model.pHasNext
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,12 @@ import QtQuick.Controls 2.4
|
||||||
Button {
|
Button {
|
||||||
id: container
|
id: container
|
||||||
property alias imageSource: image.source
|
property alias imageSource: image.source
|
||||||
|
// default button diameter -> default width, readonly
|
||||||
|
readonly property int defaultDiameter: 65
|
||||||
|
// button diameter -> width
|
||||||
|
property int diameter: defaultDiameter
|
||||||
|
// diameter of content image -> width
|
||||||
|
property int imageDiameter: 0.5*diameter
|
||||||
|
|
||||||
background: Rectangle{
|
background: Rectangle{
|
||||||
|
|
||||||
|
|
@ -15,14 +21,14 @@ Button {
|
||||||
|
|
||||||
color: "white"
|
color: "white"
|
||||||
|
|
||||||
implicitWidth: 65
|
implicitWidth: container.diameter
|
||||||
implicitHeight: width
|
implicitHeight: container.diameter
|
||||||
radius: width/2
|
radius: container.diameter/2
|
||||||
|
|
||||||
Image{
|
Image{
|
||||||
id: image
|
id: image
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: 30
|
width: container.imageDiameter
|
||||||
height: width
|
height: width
|
||||||
source: "qrc:/icon_back"
|
source: "qrc:/icon_back"
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +37,7 @@ Button {
|
||||||
z: 1
|
z: 1
|
||||||
visible: !container.enabled
|
visible: !container.enabled
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: 30
|
width: image.width
|
||||||
height: width
|
height: width
|
||||||
color: "#99ffffff"
|
color: "#99ffffff"
|
||||||
}
|
}
|
||||||
31
LenaPi/VolumeSlider.qml
Normal file
31
LenaPi/VolumeSlider.qml
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 2.4
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
property alias from: slider.from
|
||||||
|
property alias to: slider.to
|
||||||
|
property alias stepSize: slider.stepSize
|
||||||
|
property alias value: slider.value
|
||||||
|
spacing: 5
|
||||||
|
RoundImageButton{
|
||||||
|
id: increaseButton
|
||||||
|
imageSource: "qrc:///icon_increase_volume"
|
||||||
|
onClicked: slider.increase();
|
||||||
|
}
|
||||||
|
Slider{
|
||||||
|
id: slider
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
from: 34 // we cannot hear anything if lower than 35%
|
||||||
|
to: 100
|
||||||
|
stepSize: 1
|
||||||
|
value: 50
|
||||||
|
}
|
||||||
|
RoundImageButton{
|
||||||
|
id: decreaseButton
|
||||||
|
imageSource: "qrc:///icon_decrease_volume"
|
||||||
|
onClicked: slider.decrease();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,17 +10,20 @@ MusicController::MusicController(QObject *parent) : QObject(parent)
|
||||||
mVlc = new VlcInstance(VlcCommon::args(), this);
|
mVlc = new VlcInstance(VlcCommon::args(), this);
|
||||||
mModel = new MusicModel(mVlc, this);
|
mModel = new MusicModel(mVlc, this);
|
||||||
mPlayer = new VlcMediaListPlayer(mVlc);
|
mPlayer = new VlcMediaListPlayer(mVlc);
|
||||||
|
mVlcAudio = new VlcAudio(mPlayer->mediaPlayer());
|
||||||
|
|
||||||
connect(mModel, &MusicModel::navigateTo, this, &MusicController::navigateTo);
|
connect(mModel, &MusicModel::navigateTo, this, &MusicController::onNavigationRequest);
|
||||||
connect(mModel, &MusicModel::navigateTo, [this](NavigationItemModel*){
|
|
||||||
if(mModel->isPlaying()) mModel->playPause();
|
//connect(mModel, &MusicModel::play, mPlayer, &VlcMediaListPlayer::play);
|
||||||
|
connect(mModel, &MusicModel::play, [this](){
|
||||||
|
mVlcAudio->setVolume(mModel->getAudioVolume());
|
||||||
|
mPlayer->play();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(mModel, &MusicModel::play, mPlayer, &VlcMediaListPlayer::play);
|
|
||||||
connect(mModel, &MusicModel::stop, mPlayer, &VlcMediaListPlayer::stop);
|
connect(mModel, &MusicModel::stop, mPlayer, &VlcMediaListPlayer::stop);
|
||||||
connect(mModel, &MusicModel::previous, mPlayer, &VlcMediaListPlayer::previous);
|
connect(mModel, &MusicModel::previous, mPlayer, &VlcMediaListPlayer::previous);
|
||||||
connect(mModel, &MusicModel::next, mPlayer, &VlcMediaListPlayer::next);
|
connect(mModel, &MusicModel::next, mPlayer, &VlcMediaListPlayer::next);
|
||||||
connect(mModel, &MusicModel::pause, mPlayer->mediaPlayer(), &VlcMediaPlayer::pause);
|
connect(mModel, &MusicModel::pause, mPlayer->mediaPlayer(), &VlcMediaPlayer::pause);
|
||||||
|
connect(mModel, &MusicModel::audioVolumeChanged, mVlcAudio, &VlcAudio::setVolume);
|
||||||
|
|
||||||
connect(mPlayer, SIGNAL(nextItemSet(VlcMedia*)), mModel, SLOT(onNextMediaSet(VlcMedia*)));
|
connect(mPlayer, SIGNAL(nextItemSet(VlcMedia*)), mModel, SLOT(onNextMediaSet(VlcMedia*)));
|
||||||
connect(mPlayer->mediaPlayer(), &VlcMediaPlayer::lengthChanged, mModel, &MusicModel::onLengthChanged);
|
connect(mPlayer->mediaPlayer(), &VlcMediaPlayer::lengthChanged, mModel, &MusicModel::onLengthChanged);
|
||||||
|
|
@ -33,6 +36,7 @@ MusicController::MusicController(QObject *parent) : QObject(parent)
|
||||||
MusicController::~MusicController()
|
MusicController::~MusicController()
|
||||||
{
|
{
|
||||||
mPlayer->deleteLater();
|
mPlayer->deleteLater();
|
||||||
|
mVlcAudio->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicController::initPlayer(NavigationItemModel *item)
|
void MusicController::initPlayer(NavigationItemModel *item)
|
||||||
|
|
@ -58,3 +62,11 @@ void MusicController::setContextProperties()
|
||||||
if(!mContext) return;
|
if(!mContext) return;
|
||||||
mContext->setContextProperty("musicModel", mModel);
|
mContext->setContextProperty("musicModel", mModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MusicController::onNavigationRequest(NavigationItemModel *item)
|
||||||
|
{
|
||||||
|
if(mModel->isPlaying()) {
|
||||||
|
mModel->playPause();
|
||||||
|
}
|
||||||
|
emit navigateTo(item);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <VLCQtCore/Common.h>
|
#include <VLCQtCore/Common.h>
|
||||||
#include <VLCQtCore/Instance.h>
|
#include <VLCQtCore/Instance.h>
|
||||||
#include <VLCQtCore/MediaListPlayer.h>
|
#include <VLCQtCore/MediaListPlayer.h>
|
||||||
|
#include <VLCQtCore/Audio.h>
|
||||||
|
|
||||||
class MusicModel;
|
class MusicModel;
|
||||||
|
|
||||||
|
|
@ -31,12 +32,21 @@ private:
|
||||||
|
|
||||||
QQmlContext* mContext = Q_NULLPTR;
|
QQmlContext* mContext = Q_NULLPTR;
|
||||||
|
|
||||||
MusicModel* mModel;
|
MusicModel* mModel = Q_NULLPTR;
|
||||||
|
|
||||||
VlcInstance* mVlc;
|
VlcInstance* mVlc = Q_NULLPTR;
|
||||||
VlcMediaListPlayer* mPlayer;
|
VlcMediaListPlayer* mPlayer = Q_NULLPTR;
|
||||||
|
VlcAudio* mVlcAudio = Q_NULLPTR;
|
||||||
|
|
||||||
bool mIsMediaListSet = false;
|
bool mIsMediaListSet = false;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
/**
|
||||||
|
* @brief Stop player if necessary and forward signal navigatTo
|
||||||
|
* @param item target of navigation request
|
||||||
|
* @see navigateTo(NavigationItemModel* item);
|
||||||
|
*/
|
||||||
|
void onNavigationRequest(NavigationItemModel* item);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MUSICCONTROLLER_H
|
#endif // MUSICCONTROLLER_H
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,7 @@
|
||||||
<file alias="icon_previous">resources/previous.jpg</file>
|
<file alias="icon_previous">resources/previous.jpg</file>
|
||||||
<file alias="icon_stop">resources/stop.jpg</file>
|
<file alias="icon_stop">resources/stop.jpg</file>
|
||||||
<file alias="icon_close">resources/close.png</file>
|
<file alias="icon_close">resources/close.png</file>
|
||||||
|
<file alias="icon_increase_volume">resources/speaker_high_volume.png</file>
|
||||||
|
<file alias="icon_decrease_volume">resources/speaker_low_volume.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
MusicModel::MusicModel(VlcInstance* instance, QObject *parent) : QObject(parent),
|
MusicModel::MusicModel(VlcInstance* instance, QObject *parent) : QObject(parent),
|
||||||
mVlc(instance), mMedia(new VlcMediaList(instance))
|
mVlc(instance), mMedia(new VlcMediaList(instance))
|
||||||
{
|
{
|
||||||
|
/* nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
MusicModel::~MusicModel()
|
MusicModel::~MusicModel()
|
||||||
|
|
@ -101,6 +102,20 @@ bool MusicModel::hasPrevious() const
|
||||||
return mHasPrevious;
|
return mHasPrevious;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MusicModel::setAudioVolume(int newVolume)
|
||||||
|
{
|
||||||
|
if(newVolume != mAudioVolume){
|
||||||
|
if(newVolume > 100){
|
||||||
|
mAudioVolume = 100;
|
||||||
|
} else if(newVolume < 0){
|
||||||
|
mAudioVolume = 0;
|
||||||
|
} else {
|
||||||
|
mAudioVolume = newVolume;
|
||||||
|
}
|
||||||
|
emit audioVolumeChanged(mAudioVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double MusicModel::getProgress() const
|
double MusicModel::getProgress() const
|
||||||
{
|
{
|
||||||
return mCurrentMediaItemProgress;
|
return mCurrentMediaItemProgress;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ class MusicModel : public QObject
|
||||||
Q_PROPERTY(QString pMediaLength READ getMediaLength NOTIFY mediaLengthChanged)
|
Q_PROPERTY(QString pMediaLength READ getMediaLength NOTIFY mediaLengthChanged)
|
||||||
Q_PROPERTY(QString pTime READ getTime NOTIFY progressChanged)
|
Q_PROPERTY(QString pTime READ getTime NOTIFY progressChanged)
|
||||||
Q_PROPERTY(QString pMediaTitle READ getMediaTitle NOTIFY mediaTitleChanged)
|
Q_PROPERTY(QString pMediaTitle READ getMediaTitle NOTIFY mediaTitleChanged)
|
||||||
|
Q_PROPERTY(int pAudioVolume READ getAudioVolume WRITE setAudioVolume NOTIFY audioVolumeChanged)
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void navigateTo(NavigationItemModel *item);
|
void navigateTo(NavigationItemModel *item);
|
||||||
|
|
@ -33,6 +34,7 @@ signals:
|
||||||
void progressChanged();
|
void progressChanged();
|
||||||
void mediaLengthChanged();
|
void mediaLengthChanged();
|
||||||
void mediaTitleChanged();
|
void mediaTitleChanged();
|
||||||
|
void audioVolumeChanged(int newVolume);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MusicModel(VlcInstance* instance, QObject *parent = Q_NULLPTR);
|
MusicModel(VlcInstance* instance, QObject *parent = Q_NULLPTR);
|
||||||
|
|
@ -54,6 +56,15 @@ public:
|
||||||
bool hasNext() const;
|
bool hasNext() const;
|
||||||
bool hasPrevious() const;
|
bool hasPrevious() const;
|
||||||
|
|
||||||
|
inline int getAudioVolume() const { return mAudioVolume; }
|
||||||
|
/**
|
||||||
|
* @brief Set audio volume. Information is transferred to VlcAudio
|
||||||
|
* @param newVolume value between 0 and 100 (audio level in percent)
|
||||||
|
* Ensures that volume is inbetween 0 and 100. If this range is exceeded,
|
||||||
|
* the volume is set to the lowest and highest allowed value, respectively.
|
||||||
|
*/
|
||||||
|
void setAudioVolume(int newVolume);
|
||||||
|
|
||||||
double getProgress() const;
|
double getProgress() const;
|
||||||
|
|
||||||
QString getMediaTitle() const;
|
QString getMediaTitle() const;
|
||||||
|
|
@ -79,10 +90,11 @@ private:
|
||||||
int mCurrentMediaItemLength = 0;
|
int mCurrentMediaItemLength = 0;
|
||||||
int mCurrentTime = 0;
|
int mCurrentTime = 0;
|
||||||
double mCurrentMediaItemProgress = 0;
|
double mCurrentMediaItemProgress = 0;
|
||||||
|
int mAudioVolume{50};
|
||||||
QString mMediaTitle = QString("");
|
QString mMediaTitle = QString("");
|
||||||
NavigationItemModel* mCurrentItem = Q_NULLPTR;
|
NavigationItemModel* mCurrentItem = Q_NULLPTR;
|
||||||
VlcMediaList* mMedia = Q_NULLPTR;
|
VlcMediaList* mMedia = Q_NULLPTR;
|
||||||
VlcInstance* mVlc;
|
VlcInstance* mVlc = Q_NULLPTR;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MUSICMODEL_H
|
#endif // MUSICMODEL_H
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@
|
||||||
<file>MainForm.ui.qml</file>
|
<file>MainForm.ui.qml</file>
|
||||||
<file>NavigationListDelegate.qml</file>
|
<file>NavigationListDelegate.qml</file>
|
||||||
<file>MyScrollView.qml</file>
|
<file>MyScrollView.qml</file>
|
||||||
<file>RoundButton.qml</file>
|
<file>RoundImageButton.qml</file>
|
||||||
<file>Navigation.qml</file>
|
<file>Navigation.qml</file>
|
||||||
<file>MusicPlayer.qml</file>
|
<file>MusicPlayer.qml</file>
|
||||||
<file>MediaProgress.qml</file>
|
<file>MediaProgress.qml</file>
|
||||||
<file>PlayerButtons.qml</file>
|
<file>PlayerButtons.qml</file>
|
||||||
<file>PlayerControlPannel.qml</file>
|
<file>PlayerControlPannel.qml</file>
|
||||||
|
<file>VolumeSlider.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
BIN
LenaPi/resources/speaker_high_volume.png
Normal file
BIN
LenaPi/resources/speaker_high_volume.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
LenaPi/resources/speaker_low_volume.png
Normal file
BIN
LenaPi/resources/speaker_low_volume.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Loading…
Add table
Add a link
Reference in a new issue