summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2022-08-25 18:24:45 +0200
committerSimon Rettberg2022-08-25 18:24:45 +0200
commitab4bae21bda0f181c23aa8fbcd0f581441571a51 (patch)
tree7ba8c8bdcf371a5f07d9360b08fc2701cbbe6778
parentAdd comments (diff)
downloadpavucontrol-slx-ab4bae21bda0f181c23aa8fbcd0f581441571a51.tar.gz
pavucontrol-slx-ab4bae21bda0f181c23aa8fbcd0f581441571a51.tar.xz
pavucontrol-slx-ab4bae21bda0f181c23aa8fbcd0f581441571a51.zip
Big refactor, minor design tweak along the way
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/main.cpp28
-rw-r--r--src/mainwindow.cpp102
-rw-r--r--src/mainwindow.h12
-rw-r--r--src/slxoutput.cpp101
-rw-r--r--src/slxoutput.h37
-rw-r--r--src/slxoutput.ui23
7 files changed, 208 insertions, 97 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d7ff79a..709a77e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -26,11 +26,13 @@ set(pavucontrol-qt_UI
slxoutput.ui
)
+qt5_wrap_ui(pavucontrol-qt_UI_HEADERS ${pavucontrol-qt_UI})
qt5_add_resources(pavucontrol-qt_RCS resources.qrc)
add_executable(pavucontrol-qt
${pavucontrol-qt_SRCS}
${pavucontrol-qt_RCS}
+ ${pavucontrol-qt_UI_HEADERS}
)
# ${PULSE_LDFLAGS}
diff --git a/src/main.cpp b/src/main.cpp
index bf22453..adf515b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -70,35 +70,37 @@ static void updateActiveOutput()
printf(".--------------------------------------------.\n");
for (auto *sink : i->sinks()) {
- QString cardName = sink->cardIndex() < cards.size() ? cards.at(sink->cardIndex())->name() : QString();
+ PulseAudioQt::Card *card = nullptr;
+ if (sink->cardIndex() < cards.size()) {
+ card = cards.at(sink->cardIndex());
+ }
int portIndex = -1;
for (auto *port : sink->ports()) {
portIndex++;
//if (port->availability() == PulseAudioQt::Port::Unavailable)
// continue;
- bool active = (sink->isDefault() && portIndex == sink->activePortIndex());
+ bool portIsActive = portIndex == sink->activePortIndex();
+ bool defaultSinkAndPort = (sink->isDefault() && portIsActive);
qint64 volume = sink->volume();
printf("[%c] Output: '%s %s', volume: %d, mute: %d\n",
- active ? 'x' : ' ',
+ defaultSinkAndPort ? 'x' : ' ',
sink->description().toLocal8Bit().constData(), port->description().toLocal8Bit().constData(),
(int)volume, (int)sink->isMuted());
- QString id = cardName + sink->name() + port->name();
+ QString id = sink->name() + port->name();
// Only once, update port volume to be 100% if it's low
- if (active && !_donePorts.contains(id)) {
+ if (defaultSinkAndPort && !_donePorts.contains(id)) {
_donePorts.insert(id);
if (volume < 60000) {
volume = 65535;
sink->setVolume(volume);
}
}
- QString title = sink->description() + ", " + port->description();
- _mainWindow->getOutput(id, true, title)->updateOutput(title,
- active, sink->isMuted(), sink->isVolumeWritable() ? sink->volume() : -1, QString(), sink->name(), port->name());
+ _mainWindow->getDevice(card, sink, port)->updateDeviceAndPort(defaultSinkAndPort, sink->isMuted(),
+ (portIsActive && sink->isVolumeWritable()) ? sink->volume() : -1);
}
}
// Now find all the profiles from all cards that are not active and add an entry to the list for each one
for (auto *card : cards) {
- QString cardDescription = card->description();
int profIndex = -1;
for (auto *profile : card->profiles()) {
profIndex++;
@@ -110,10 +112,7 @@ static void updateActiveOutput()
continue;
printf("[ ] Output: '%s', sinks: %d\n",
profile->description().toLocal8Bit().constData(), profile->sinks());
- QString id = card->name() + profile->name();
- QString title = cardDescription + ", " + profile->description();
- _mainWindow->getOutput(id, false, title)->updateOutput(title,
- false, false, -1, card->name(), QString(), profile->name());
+ _mainWindow->getCardProfile(card, profile)->updateCardAndProfile();
}
}
printf("`--------------------------------------------ยด\n");
@@ -341,6 +340,9 @@ int main(int argc, char **argv)
for (auto *profile : card->profiles()) {
printf(" Profile: %s\n", profile->name().toLocal8Bit().constData());
}
+ for (auto *port : card->ports()) {
+ printf(" Port: %s\n", port->name().toLocal8Bit().constData());
+ }
}
for (auto *sink : i->sinks()) {
printf("Sink: %s (for card index %d)\n", sink->name().toLocal8Bit().constData(), sink->cardIndex());
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 9ae66d3..b35a8f9 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1,6 +1,11 @@
#include "mainwindow.h"
#include "slxoutput.h"
+#include <PulseAudioQt/Sink>
+#include <PulseAudioQt/Port>
+#include <PulseAudioQt/Card>
+#include <PulseAudioQt/Profile>
+
MainWindow::MainWindow() : QDialog()
{
setupUi(this);
@@ -12,43 +17,80 @@ MainWindow::~MainWindow()
}
-SlxOutput* MainWindow::getOutput(const QString &id, bool isSink, const QString &newTitle)
+SlxOutput* MainWindow::getDevice(const PulseAudioQt::Card *card, const PulseAudioQt::Sink *sink, const PulseAudioQt::Port *port)
+{
+ PulseAudioQt::Profile *profile = nullptr;
+ QString cardId;
+ QString id = sink->name() + port->name();
+ SlxOutput* w = _widgets.value(id, nullptr);
+ QString heading = port->description();
+
+ if (card != nullptr) {
+ cardId = card->name();
+ if (card->activeProfileIndex() < card->profiles().size()) {
+ profile = card->profiles().at(card->activeProfileIndex());
+ heading.append(QLatin1String(" (")).append(profile->description()).append(QLatin1String(")"));
+ }
+ }
+ if (w != nullptr) {
+ w->headingLabel->setText(heading);
+ return w;
+ }
+
+ w = new SlxOutput(SlxOutput::SinkPortItem, id, cardId, QLatin1String(), sink->name(), port->name(),
+ heading, sink->description());
+ _widgets.insert(id, w);
+
+ insertItemWidget(w, true);
+ return w;
+}
+
+SlxOutput* MainWindow::getCardProfile(const PulseAudioQt::Card *card, const PulseAudioQt::Profile *profile)
{
+
+ QString id = card->name() + profile->name();
SlxOutput* w = _widgets.value(id, nullptr);
- if (w == nullptr) {
- w = new SlxOutput(nullptr, id);
- _widgets.insert(id, w);
- bool done = false;
- printf("New %s - %s\n", isSink ? "SINK" : "PROF", newTitle.toLocal8Bit().constData());
- printf("Conteints: %d\n", container->count());
- int idx;
- for (idx = 0; idx < container->count(); ++idx) {
- auto *l = container->itemAt(idx);
- SlxOutput *other = qobject_cast<SlxOutput*>(l->widget());
- if (other == nullptr)
- continue;
- printf(" Comparing %s - %s\n", other->isSink() ? "SINK" : "PROF", other->nameLabel->text().toLocal8Bit().constData());
- if (isSink != other->isSink()) {
- if (isSink)
- break;
- continue;
- }
- if (newTitle.compare(other->nameLabel->text()) < 0) {
- done = true;
- printf("Inserting before that (%d)!\n", idx);
- container->insertWidget(idx, w);
+ if (w != nullptr)
+ return w;
+
+ w = new SlxOutput(SlxOutput::CardProfileItem, id, card->name(), profile->name(), QLatin1String(), QLatin1String(),
+ profile->description(), card->description());
+ _widgets.insert(id, w);
+
+ insertItemWidget(w, false);
+ return w;
+}
+
+void MainWindow::insertItemWidget(SlxOutput* w, bool isDevice)
+{
+ bool done = false;
+ int idx;
+
+ for (idx = 0; idx < container->count(); ++idx) {
+ auto *l = container->itemAt(idx);
+ SlxOutput *other = qobject_cast<SlxOutput*>(l->widget());
+ if (other == nullptr)
+ continue;
+ printf(" Comparing %s - %s\n", other->isDevice() ? "SINK" : "PROF", other->nameLabel->text().toLocal8Bit().constData());
+ if (isDevice != other->isDevice()) {
+ if (isDevice)
break;
- }
+ continue;
}
- if (!done) {
- if (idx == -1) {
- idx = 0;
- }
- printf("Inserting before that (%d) 2!\n", idx);
+ if (w->compareTo(other) < 0) {
+ done = true;
+ printf("Inserting before that (%d)!\n", idx);
container->insertWidget(idx, w);
+ break;
}
}
- return w;
+ if (!done) {
+ if (idx == -1) {
+ idx = 0;
+ }
+ printf("Inserting before that (%d) 2!\n", idx);
+ container->insertWidget(idx, w);
+ }
}
/**
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 7f792c5..6fbe9f2 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -7,6 +7,13 @@
#include "ui_mainwindow.h"
class SlxOutput;
+namespace PulseAudioQt {
+class Sink;
+class Port;
+class Source;
+class Card;
+class Profile;
+}
class MainWindow : public QDialog, public Ui::MainWindow
{
@@ -16,7 +23,10 @@ public:
MainWindow();
virtual ~MainWindow();
- SlxOutput* getOutput(const QString &id, bool isSink, const QString &newTitle);
+ SlxOutput* getDevice(const PulseAudioQt::Card *card, const PulseAudioQt::Sink *sink, const PulseAudioQt::Port *port);
+ SlxOutput* getCardProfile(const PulseAudioQt::Card *card, const PulseAudioQt::Profile *profile);
+
+ void insertItemWidget(SlxOutput* w, bool isDevice);
void mark();
void sweep();
diff --git a/src/slxoutput.cpp b/src/slxoutput.cpp
index 0ac38b1..5bc319b 100644
--- a/src/slxoutput.cpp
+++ b/src/slxoutput.cpp
@@ -1,44 +1,66 @@
#include "slxoutput.h"
#include "main.h"
-SlxOutput::SlxOutput(QWidget *parent, const QString &id)
+SlxOutput::SlxOutput(ItemType type, const QString &id,
+ const QString &card, const QString &profile,
+ const QString &sink, const QString &port,
+ const QString &heading, const QString &title)
: unused(false),
- QWidget(parent),
- _id(id)
+ _id(id),
+ _type(type),
+ _cardId(card),
+ _profileId(profile),
+ _deviceId(sink),
+ _portId(port),
+ QWidget(nullptr)
{
setupUi(this);
- volumeSlider->setMaximum(65535);
- volumeSlider->setSingleStep(200);
- volumeSlider->setSingleStep(2000);
- _volumeTimer.setInterval(100);
- _volumeTimer.setSingleShot(true);
- // Events
- connect(muteToggleButton, &QToolButton::toggled, [this]() {
- if (g_IgnoreGui)
- return;
- if (_sink.isEmpty())
- return;
- setMuted(_sink, muteToggleButton->isChecked());
- });
+ // Make heading 25% larger than system default
+ QFont f = headingLabel->font();
+ f.setPointSize(f.pointSize() * 5 / 4);
+ f.setBold(_type == SinkPortItem || _type == SourcePortItem);
+ headingLabel->setFont(f);
+ //
+ if (_type == SinkPortItem || _type == SourcePortItem) {
+ volumeSlider->setMaximum(65535);
+ volumeSlider->setSingleStep(200);
+ volumeSlider->setSingleStep(2000);
+ _volumeTimer.setInterval(100);
+ _volumeTimer.setSingleShot(true);
+ // Events
+ connect(muteToggleButton, &QToolButton::toggled, [this]() {
+ if (g_IgnoreGui)
+ return;
+ if (_deviceId.isEmpty())
+ return;
+ setMuted(_deviceId, muteToggleButton->isChecked());
+ });
+ connect(volumeSlider, &QSlider::sliderMoved, this, &SlxOutput::volumeSliderChanged);
+ connect(volumeSlider, &QSlider::valueChanged, this, &SlxOutput::volumeSliderChanged);
+ connect(&_volumeTimer, &QTimer::timeout, [this]() {
+ if (g_IgnoreGui || !isDevice())
+ return;
+ setSinkVolume(_deviceId, volumeSlider->value());
+ });
+ } else {
+ volumeSlider->setEnabled(false);
+ muteToggleButton->setEnabled(false);
+ }
+ nameLabel->setText(title);
+ headingLabel->setText(heading);
+ // Default Toggle
connect(defaultToggleButton, &QToolButton::toggled, [this]() {
if (g_IgnoreGui)
return;
if (!defaultToggleButton->isChecked()) {
defaultToggleButton->setChecked(true);
}
- if (_sink.isEmpty()) {
- enableCard(_card, _port);
+ if (_type == CardProfileItem) {
+ enableCard(_cardId, _profileId);
} else {
- enableSink(_sink, _port);
+ enableSink(_deviceId, _portId);
}
});
- connect(volumeSlider, &QSlider::sliderMoved, this, &SlxOutput::volumeSliderChanged);
- connect(volumeSlider, &QSlider::valueChanged, this, &SlxOutput::volumeSliderChanged);
- connect(&_volumeTimer, &QTimer::timeout, [this]() {
- if (g_IgnoreGui || !isSink())
- return;
- setSinkVolume(_sink, volumeSlider->value());
- });
}
SlxOutput::~SlxOutput()
@@ -56,28 +78,31 @@ void SlxOutput::volumeSliderChanged(int value)
_volumeTimer.start();
}
-void SlxOutput::updateOutput(const QString &name, bool isDefault, bool isMuted, int volume, const QString &card, const QString &sink, const QString &port)
+/**
+ * Update this entry, which has to represent a sink/source plus one of its ports.
+ */
+void SlxOutput::updateDeviceAndPort(bool isDefault, bool isMuted, int volume)
{
- nameLabel->setText(name);
- if (sink != _sink) {
- QFont fi = nameLabel->font();
- fi.setBold(!sink.isEmpty());
- nameLabel->setFont(fi);
- }
- _card = card;
- _sink = sink;
- _port = port;
defaultToggleButton->setChecked(isDefault);
muteToggleButton->setChecked(isMuted);
if (volume == -1) {
volumeSlider->setEnabled(false);
+ muteToggleButton->setEnabled(false);
} else {
if (volume > volumeSlider->maximum()) {
volumeSlider->setMaximum(volume);
}
volumeSlider->setValue(volume);
- volumeSlider->setEnabled(isSink());
+ volumeSlider->setEnabled(true);
+ muteToggleButton->setEnabled(true);
}
- muteToggleButton->setEnabled(isSink());
+ unused = false; // Entry was updated, so it's being used
+}
+
+/**
+ * Update this entry, which has to represent a card plus one of its profiles.
+ */
+void SlxOutput::updateCardAndProfile()
+{
unused = false; // Entry was updated, so it's being used
}
diff --git a/src/slxoutput.h b/src/slxoutput.h
index 15f8554..c175899 100644
--- a/src/slxoutput.h
+++ b/src/slxoutput.h
@@ -10,20 +10,43 @@ class SlxOutput : public QWidget, public Ui::SlxOutput
{
Q_OBJECT
public:
- SlxOutput(QWidget *parent, const QString &id);
+
+ enum ItemType {
+ UnknownItem,
+ SinkPortItem,
+ SourcePortItem,
+ CardProfileItem,
+ };
+
+ SlxOutput(ItemType type, const QString &id,
+ const QString &card, const QString &profile,
+ const QString &sink, const QString &port,
+ const QString &heading, const QString &title);
virtual ~SlxOutput();
- void updateOutput(const QString &name, bool isDefault, bool isMuted, int volume, const QString &card, const QString &sink, const QString &port);
- const QString &sink() const { return _sink; }
- const bool isSink() const { return !_sink.isEmpty(); }
+ void updateDeviceAndPort(bool isDefault, bool isMuted, int volume);
+ void updateCardAndProfile();
+
+ const QString &deviceId() const { return _deviceId; }
+ const bool isDevice() const { return !_deviceId.isEmpty(); }
+
+ int compareTo(SlxOutput* other) const
+ {
+ int c = this->nameLabel->text().compare(other->nameLabel->text());
+ if (c != 0)
+ return c;
+ return this->headingLabel->text().compare(other->headingLabel->text());
+ }
bool unused;
private:
+ ItemType _type;
QString _id;
- QString _card;
- QString _sink;
- QString _port;
+ QString _cardId;
+ QString _profileId;
+ QString _deviceId;
+ QString _portId;
QTimer _volumeTimer;
private slots:
diff --git a/src/slxoutput.ui b/src/slxoutput.ui
index 3516d82..55bf300 100644
--- a/src/slxoutput.ui
+++ b/src/slxoutput.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>400</width>
- <height>81</height>
+ <height>102</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,6 +15,13 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
+ <widget class="QLabel" name="headingLabel">
+ <property name="text">
+ <string>Profile/Port/Sink/Source</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="defaultToggleButton">
@@ -23,9 +30,8 @@
</property>
<property name="icon">
<iconset resource="resources.qrc">
- <normaloff>:/none</normaloff>
- <normalon>:/checkmark</normalon>
- </iconset>
+ <normaloff>:/none</normaloff>
+ <normalon>:/checkmark</normalon>:/none</iconset>
</property>
<property name="iconSize">
<size>
@@ -65,9 +71,8 @@
</property>
<property name="icon">
<iconset resource="resources.qrc">
- <normaloff>:/mute-off</normaloff>
- <normalon>:/mute-on</normalon>
- </iconset>
+ <normaloff>:/mute-off</normaloff>
+ <normalon>:/mute-on</normalon>:/mute-off</iconset>
</property>
<property name="iconSize">
<size>
@@ -98,6 +103,8 @@
</item>
</layout>
</widget>
- <resources/>
+ <resources>
+ <include location="resources.qrc"/>
+ </resources>
<connections/>
</ui>