add a combobox to the streams page, to filter application streams

git-svn-id: file:///home/lennart/svn/public/pavucontrol/trunk@59 c17c95f2-f111-0410-90bf-f30a9569010c
This commit is contained in:
Lennart Poettering 2007-08-31 01:16:50 +00:00
parent 4de2617bcd
commit e6846ac8ac
2 changed files with 179 additions and 52 deletions

View File

@ -38,6 +38,12 @@
static pa_context *context = NULL; static pa_context *context = NULL;
static int n_outstanding = 0; static int n_outstanding = 0;
enum SinkInputType {
SINK_INPUT_ALL,
SINK_INPUT_CLIENT,
SINK_INPUT_VIRTUAL
};
enum SinkType { enum SinkType {
SINK_ALL, SINK_ALL,
SINK_HARDWARE, SINK_HARDWARE,
@ -135,6 +141,8 @@ public:
static SinkInputWidget* create(); static SinkInputWidget* create();
virtual ~SinkInputWidget(); virtual ~SinkInputWidget();
SinkInputType type;
uint32_t index, clientIndex, sinkIndex; uint32_t index, clientIndex, sinkIndex;
virtual void executeVolumeUpdate(); virtual void executeVolumeUpdate();
virtual void onMuteToggleButton(); virtual void onMuteToggleButton();
@ -186,16 +194,18 @@ public:
Gtk::VBox *streamsVBox, *sinksVBox, *sourcesVBox; Gtk::VBox *streamsVBox, *sinksVBox, *sourcesVBox;
Gtk::EventBox *titleEventBox; Gtk::EventBox *titleEventBox;
Gtk::Label *noStreamsLabel, *noSinksLabel, *noSourcesLabel; Gtk::Label *noStreamsLabel, *noSinksLabel, *noSourcesLabel;
Gtk::ComboBox *sinkTypeComboBox, *sourceTypeComboBox; Gtk::ComboBox *sinkInputTypeComboBox, *sinkTypeComboBox, *sourceTypeComboBox;
std::map<uint32_t, SinkWidget*> sinkWidgets; std::map<uint32_t, SinkWidget*> sinkWidgets;
std::map<uint32_t, SourceWidget*> sourceWidgets; std::map<uint32_t, SourceWidget*> sourceWidgets;
std::map<uint32_t, SinkInputWidget*> streamWidgets; std::map<uint32_t, SinkInputWidget*> sinkInputWidgets;
std::map<uint32_t, char*> clientNames; std::map<uint32_t, char*> clientNames;
SinkInputType showSinkInputType;
SinkType showSinkType; SinkType showSinkType;
SourceType showSourceType; SourceType showSourceType;
virtual void onSinkInputTypeComboBoxChanged();
virtual void onSinkTypeComboBoxChanged(); virtual void onSinkTypeComboBoxChanged();
virtual void onSourceTypeComboBoxChanged(); virtual void onSourceTypeComboBoxChanged();
@ -522,6 +532,7 @@ void SinkInputWidget::SinkMenuItem::onToggle() {
MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x) : MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x) :
Gtk::Window(cobject), Gtk::Window(cobject),
showSinkInputType(SINK_INPUT_CLIENT),
showSinkType(SINK_ALL), showSinkType(SINK_ALL),
showSourceType(SOURCE_NO_MONITOR) { showSourceType(SOURCE_NO_MONITOR) {
@ -532,6 +543,7 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade:
x->get_widget("noStreamsLabel", noStreamsLabel); x->get_widget("noStreamsLabel", noStreamsLabel);
x->get_widget("noSinksLabel", noSinksLabel); x->get_widget("noSinksLabel", noSinksLabel);
x->get_widget("noSourcesLabel", noSourcesLabel); x->get_widget("noSourcesLabel", noSourcesLabel);
x->get_widget("sinkInputTypeComboBox", sinkInputTypeComboBox);
x->get_widget("sinkTypeComboBox", sinkTypeComboBox); x->get_widget("sinkTypeComboBox", sinkTypeComboBox);
x->get_widget("sourceTypeComboBox", sourceTypeComboBox); x->get_widget("sourceTypeComboBox", sourceTypeComboBox);
@ -539,9 +551,11 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade:
streamsVBox->set_reallocate_redraws(true); streamsVBox->set_reallocate_redraws(true);
sinksVBox->set_reallocate_redraws(true); sinksVBox->set_reallocate_redraws(true);
sinkInputTypeComboBox->set_active((int) showSinkInputType);
sinkTypeComboBox->set_active((int) showSinkType); sinkTypeComboBox->set_active((int) showSinkType);
sourceTypeComboBox->set_active((int) showSourceType); sourceTypeComboBox->set_active((int) showSourceType);
sinkInputTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSinkInputTypeComboBoxChanged));
sinkTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSinkTypeComboBoxChanged)); sinkTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSinkTypeComboBoxChanged));
sourceTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSourceTypeComboBoxChanged)); sourceTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSourceTypeComboBoxChanged));
@ -637,20 +651,24 @@ void MainWindow::updateSource(const pa_source_info &info) {
void MainWindow::updateSinkInput(const pa_sink_input_info &info) { void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
SinkInputWidget *w; SinkInputWidget *w;
bool is_new = false;
if (streamWidgets.count(info.index)) if (sinkInputWidgets.count(info.index))
w = streamWidgets[info.index]; w = sinkInputWidgets[info.index];
else { else {
streamWidgets[info.index] = w = SinkInputWidget::create(); sinkInputWidgets[info.index] = w = SinkInputWidget::create();
w->setChannelMap(info.channel_map); w->setChannelMap(info.channel_map);
streamsVBox->pack_start(*w, false, false, 0); streamsVBox->pack_start(*w, false, false, 0);
w->index = info.index; w->index = info.index;
w->clientIndex = info.client; w->clientIndex = info.client;
w->mainWindow = this; w->mainWindow = this;
is_new = true;
} }
w->updating = true; w->updating = true;
w->type = info.client != PA_INVALID_INDEX ? SINK_INPUT_CLIENT : SINK_INPUT_VIRTUAL;
w->sinkIndex = info.sink; w->sinkIndex = info.sink;
char *txt; char *txt;
@ -664,11 +682,11 @@ void MainWindow::updateSinkInput(const pa_sink_input_info &info) {
w->nameLabel->set_label(info.name); w->nameLabel->set_label(info.name);
} }
w->muteToggleButton->set_active(info.mute);
w->setVolume(info.volume); w->setVolume(info.volume);
w->muteToggleButton->set_active(info.mute);
w->show(); if (is_new)
updateDeviceVisibility(); updateDeviceVisibility();
w->updating = false; w->updating = false;
} }
@ -678,7 +696,7 @@ void MainWindow::updateClient(const pa_client_info &info) {
g_free(clientNames[info.index]); g_free(clientNames[info.index]);
clientNames[info.index] = g_strdup(info.name); clientNames[info.index] = g_strdup(info.name);
for (std::map<uint32_t, SinkInputWidget*>::iterator i = streamWidgets.begin(); i != streamWidgets.end(); ++i) { for (std::map<uint32_t, SinkInputWidget*>::iterator i = sinkInputWidgets.begin(); i != sinkInputWidgets.end(); ++i) {
SinkInputWidget *w = i->second; SinkInputWidget *w = i->second;
if (!w) if (!w)
@ -694,16 +712,26 @@ void MainWindow::updateClient(const pa_client_info &info) {
void MainWindow::updateDeviceVisibility() { void MainWindow::updateDeviceVisibility() {
if (streamWidgets.empty()) streamsVBox->hide_all();
noStreamsLabel->show();
else
noStreamsLabel->hide();
sourcesVBox->hide_all(); sourcesVBox->hide_all();
sinksVBox->hide_all(); sinksVBox->hide_all();
bool is_empty = true; bool is_empty = true;
for (std::map<uint32_t, SinkInputWidget*>::iterator i = sinkInputWidgets.begin(); i != sinkInputWidgets.end(); ++i) {
SinkInputWidget* w = i->second;
if (showSinkInputType == SINK_INPUT_ALL || w->type == showSinkInputType) {
w->show_all();
is_empty = false;
}
}
if (is_empty)
noStreamsLabel->show();
is_empty = true;
for (std::map<uint32_t, SinkWidget*>::iterator i = sinkWidgets.begin(); i != sinkWidgets.end(); ++i) { for (std::map<uint32_t, SinkWidget*>::iterator i = sinkWidgets.begin(); i != sinkWidgets.end(); ++i) {
SinkWidget* w = i->second; SinkWidget* w = i->second;
@ -734,6 +762,7 @@ void MainWindow::updateDeviceVisibility() {
sourcesVBox->show(); sourcesVBox->show();
sinksVBox->show(); sinksVBox->show();
streamsVBox->show();
} }
void MainWindow::removeSink(uint32_t index) { void MainWindow::removeSink(uint32_t index) {
@ -755,11 +784,11 @@ void MainWindow::removeSource(uint32_t index) {
} }
void MainWindow::removeSinkInput(uint32_t index) { void MainWindow::removeSinkInput(uint32_t index) {
if (!streamWidgets.count(index)) if (!sinkInputWidgets.count(index))
return; return;
delete streamWidgets[index]; delete sinkInputWidgets[index];
streamWidgets.erase(index); sinkInputWidgets.erase(index);
updateDeviceVisibility(); updateDeviceVisibility();
} }
@ -786,6 +815,15 @@ void MainWindow::onSourceTypeComboBoxChanged() {
updateDeviceVisibility(); updateDeviceVisibility();
} }
void MainWindow::onSinkInputTypeComboBoxChanged() {
showSinkInputType = (SinkInputType) sinkInputTypeComboBox->get_active_row_number();
if (showSinkInputType == (SinkInputType) -1)
sinkInputTypeComboBox->set_active((int) SINK_INPUT_CLIENT);
updateDeviceVisibility();
}
static void dec_outstanding(MainWindow *w) { static void dec_outstanding(MainWindow *w) {
if (n_outstanding <= 0) if (n_outstanding <= 0)
return; return;

View File

@ -100,6 +100,7 @@
<child> <child>
<widget class="GtkViewport" id="viewport1"> <widget class="GtkViewport" id="viewport1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child> <child>
<widget class="GtkVBox" id="streamsVBox"> <widget class="GtkVBox" id="streamsVBox">
<property name="visible">True</property> <property name="visible">True</property>
@ -133,34 +134,60 @@
<child> <child>
<widget class="GtkHBox" id="hbox5"> <widget class="GtkHBox" id="hbox5">
<property name="visible">True</property> <property name="visible">True</property>
<property name="homogeneous">True</property> <property name="spacing">6</property>
<child> <child>
<widget class="GtkHBox" id="hbox6"> <widget class="GtkImage" id="image21">
<property name="visible">True</property> <property name="visible">True</property>
<property name="spacing">6</property> <property name="xalign">1</property>
<child> <property name="stock">gtk-dialog-info</property>
<widget class="GtkImage" id="image21"> </widget>
<property name="visible">True</property> <packing>
<property name="xalign">1</property> <property name="expand">False</property>
<property name="icon_size">6</property> </packing>
<property name="icon_name">gtk-dialog-info</property> </child>
</widget> <child>
</child> <widget class="GtkAlignment" id="alignment6">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="right_padding">12</property>
<child> <child>
<widget class="GtkLabel" id="label4828"> <widget class="GtkLabel" id="label4828">
<property name="visible">True</property> <property name="visible">True</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Hint:&lt;/b&gt; Right click on a playback stream to move it to another output device.</property> <property name="label" translatable="yes">&lt;b&gt;Hint:&lt;/b&gt; &lt;i&gt;Right click on a playback stream to move it to another output device.&lt;/i&gt;</property>
<property name="use_markup">True</property> <property name="use_markup">True</property>
</widget> </widget>
<packing>
<property name="position">1</property>
</packing>
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;_Show:&lt;/b&gt;</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="sinkInputTypeComboBox">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="items" translatable="yes" comments="Applications&#10;All streams">All Streams
Applications
Virtual Streams</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing> </packing>
</child> </child>
</widget> </widget>
@ -180,7 +207,7 @@
<child> <child>
<widget class="GtkLabel" id="label34"> <widget class="GtkLabel" id="label34">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">S_treams</property> <property name="label" translatable="yes">_Playback</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
</widget> </widget>
<packing> <packing>
@ -202,6 +229,7 @@
<child> <child>
<widget class="GtkViewport" id="viewport4"> <widget class="GtkViewport" id="viewport4">
<property name="visible">True</property> <property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child> <child>
<widget class="GtkVBox" id="sinksVBox"> <widget class="GtkVBox" id="sinksVBox">
<property name="visible">True</property> <property name="visible">True</property>
@ -236,28 +264,58 @@
<widget class="GtkHBox" id="hbox3"> <widget class="GtkHBox" id="hbox3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<child>
<widget class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="stock">gtk-dialog-info</property>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment5">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="right_padding">12</property>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Hint:&lt;/b&gt; &lt;i&gt;Right click on an output device to make it the default.&lt;/i&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="label4826"> <widget class="GtkLabel" id="label4826">
<property name="visible">True</property> <property name="visible">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;S_how:&lt;/b&gt;</property> <property name="label" translatable="yes">&lt;b&gt;S_how:&lt;/b&gt;</property>
<property name="use_markup">True</property> <property name="use_markup">True</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="mnemonic_widget">sinkTypeComboBox</property> <property name="mnemonic_widget">sinkTypeComboBox</property>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="position">2</property>
<property name="fill">False</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkComboBox" id="sinkTypeComboBox"> <widget class="GtkComboBox" id="sinkTypeComboBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="items" translatable="yes">All Sinks <property name="items" translatable="yes">All Output Devices
Hardware Sinks Hardware Output Devices
Virtual Sinks</property> Virtual Output Devices</property>
</widget> </widget>
<packing> <packing>
<property name="position">1</property> <property name="expand">False</property>
<property name="position">3</property>
</packing> </packing>
</child> </child>
</widget> </widget>
@ -277,7 +335,7 @@ Virtual Sinks</property>
<child> <child>
<widget class="GtkLabel" id="label4711"> <widget class="GtkLabel" id="label4711">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">S_inks</property> <property name="label" translatable="yes">_Output Devices</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
</widget> </widget>
<packing> <packing>
@ -300,6 +358,7 @@ Virtual Sinks</property>
<child> <child>
<widget class="GtkViewport" id="viewport3"> <widget class="GtkViewport" id="viewport3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child> <child>
<widget class="GtkVBox" id="sourcesVBox"> <widget class="GtkVBox" id="sourcesVBox">
<property name="visible">True</property> <property name="visible">True</property>
@ -334,30 +393,60 @@ Virtual Sinks</property>
<widget class="GtkHBox" id="hbox4"> <widget class="GtkHBox" id="hbox4">
<property name="visible">True</property> <property name="visible">True</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<child>
<widget class="GtkImage" id="image5">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="stock">gtk-dialog-info</property>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="right_padding">12</property>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Hint:&lt;/b&gt; &lt;i&gt;Right click on an input device to make it the default.&lt;/i&gt;</property>
<property name="use_markup">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="label4827"> <widget class="GtkLabel" id="label4827">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Sh_ow:&lt;/b&gt;</property> <property name="xalign">1</property>
<property name="label" translatable="yes">&lt;b&gt;Sho_w:&lt;/b&gt;</property>
<property name="use_markup">True</property> <property name="use_markup">True</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="mnemonic_widget">sourceTypeComboBox</property> <property name="mnemonic_widget">sourceTypeComboBox</property>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="position">2</property>
<property name="fill">False</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkComboBox" id="sourceTypeComboBox"> <widget class="GtkComboBox" id="sourceTypeComboBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="items" translatable="yes">All Sources <property name="items" translatable="yes">All Input Devices
All Except Monitor Sources All Except Monitors
Hardware Sources Hardware Input Devices
Virtual Sources Virtual Input Devices
Monitor Sources</property> Monitors</property>
</widget> </widget>
<packing> <packing>
<property name="position">1</property> <property name="expand">False</property>
<property name="position">3</property>
</packing> </packing>
</child> </child>
</widget> </widget>
@ -377,7 +466,7 @@ Monitor Sources</property>
<child> <child>
<widget class="GtkLabel" id="label4717"> <widget class="GtkLabel" id="label4717">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">S_ources</property> <property name="label" translatable="yes">_Input Devices</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
</widget> </widget>
<packing> <packing>