summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorColin Guthrie <cguthrie@mandriva.org>2009-06-13 19:15:02 +0100
committerColin Guthrie <cguthrie@mandriva.org>2009-06-17 08:54:14 +0100
commit02b316fcba8a112e528a0bddfcb93cf6f3179168 (patch)
tree96471135e9d83af7ebb275d77e71c9d0c0b6033d /src
parente71562619a67fa6823ba5d14c3df411b12fe192b (diff)
More changes in the UI to try and make things neater.
This abandons the combo box approach an instead partially reverts to the popup. We now display a suffix after the stream title saying " on <device>" or " from <device>" where the <device> part looks like a hyperlink and, when clicked, shows the popup to change the device. If there is only one device available, we suppress the whole thing and thus avoid confusion.
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.cc79
-rw-r--r--src/mainwindow.h23
-rw-r--r--src/pavucontrol.glade102
-rw-r--r--src/rolewidget.cc6
-rw-r--r--src/rolewidget.h1
-rw-r--r--src/sinkinputwidget.cc87
-rw-r--r--src/sinkinputwidget.h25
-rw-r--r--src/sourceoutputwidget.cc84
-rw-r--r--src/sourceoutputwidget.h25
-rw-r--r--src/streamwidget.cc15
-rw-r--r--src/streamwidget.h10
11 files changed, 249 insertions, 208 deletions
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index f76f37a..5e6b464 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -86,9 +86,6 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade:
sourceOutputTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSourceOutputTypeComboBoxChanged));
sinkTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSinkTypeComboBoxChanged));
sourceTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSourceTypeComboBoxChanged));
-
- sinkTree = Gtk::ListStore::create(deviceColumns);
- sourceTree = Gtk::ListStore::create(deviceColumns);
}
MainWindow* MainWindow::create() {
@@ -179,34 +176,6 @@ void MainWindow::updateCard(const pa_card_info &info) {
updateDeviceVisibility();
}
-void MainWindow::rebuildSinkCombo() {
- uint32_t idx = 0;
- Gtk::TreeModel::Row row;
-
- sinkTree->clear();
- sinkTreeIndexes.clear();
-
- /*
- row = *(sinkTree->append());
- idx++;
- row[deviceColumns.index] = -1;
- row[deviceColumns.name] = "Default Output";
- */
-
- for (std::map<uint32_t, SinkWidget*>::iterator i = sinkWidgets.begin(); i != sinkWidgets.end(); ++i) {
- Gtk::TreeModel::Row row = *(sinkTree->append());
- sinkTreeIndexes[i->first] = idx++;
- row[deviceColumns.index] = i->first;
- row[deviceColumns.name] = i->second->description.c_str();
- }
-
- /* Force a redraw of the dropdown combo due to the model change. */
- for (std::map<uint32_t, SinkInputWidget*>::iterator i = sinkInputWidgets.begin(); i != sinkInputWidgets.end(); ++i) {
- SinkInputWidget* w = i->second;
- w->setSinkIndex(w->sinkIndex());
- }
-}
-
void MainWindow::updateSink(const pa_sink_info &info) {
SinkWidget *w;
bool is_new = false;
@@ -250,7 +219,6 @@ void MainWindow::updateSink(const pa_sink_info &info) {
w->updating = false;
- rebuildSinkCombo();
if (is_new)
updateDeviceVisibility();
}
@@ -356,34 +324,6 @@ void MainWindow::createMonitorStreamForSinkInput(uint32_t sink_input_idx, uint32
}
}
-void MainWindow::rebuildSourceCombo() {
- uint32_t idx = 0;
- Gtk::TreeModel::Row row;
-
- sourceTree->clear();
- sourceTreeIndexes.clear();
-
- /*
- row = *(sourceTree->append());
- idx++;
- row[deviceColumns.index] = -1;
- row[deviceColumns.name] = "Default Input";
- */
-
- for (std::map<uint32_t, SourceWidget*>::iterator i = sourceWidgets.begin(); i != sourceWidgets.end(); ++i) {
- Gtk::TreeModel::Row row = *(sourceTree->append());
- sourceTreeIndexes[i->first] = idx++;
- row[deviceColumns.index] = i->first;
- row[deviceColumns.name] = i->second->description.c_str();
- }
-
- /* Force a redraw of the dropdown combo due to the model change. */
- for (std::map<uint32_t, SourceOutputWidget*>::iterator i = sourceOutputWidgets.begin(); i != sourceOutputWidgets.end(); ++i) {
- SourceOutputWidget* w = i->second;
- w->setSourceIndex(w->sourceIndex());
- }
-}
-
void MainWindow::updateSource(const pa_source_info &info) {
SourceWidget *w;
bool is_new = false;
@@ -428,7 +368,6 @@ void MainWindow::updateSource(const pa_source_info &info) {
w->updating = false;
- rebuildSourceCombo();
if (is_new)
updateDeviceVisibility();
}
@@ -737,6 +676,14 @@ void MainWindow::reallyUpdateDeviceVisibility() {
for (std::map<uint32_t, SinkInputWidget*>::iterator i = sinkInputWidgets.begin(); i != sinkInputWidgets.end(); ++i) {
SinkInputWidget* w = i->second;
+ if (sinkWidgets.size() > 1) {
+ w->directionLabel->show();
+ w->deviceButton->show();
+ } else {
+ w->directionLabel->hide();
+ w->deviceButton->hide();
+ }
+
if (showSinkInputType == SINK_INPUT_ALL || w->type == showSinkInputType) {
w->show();
is_empty = false;
@@ -757,6 +704,14 @@ void MainWindow::reallyUpdateDeviceVisibility() {
for (std::map<uint32_t, SourceOutputWidget*>::iterator i = sourceOutputWidgets.begin(); i != sourceOutputWidgets.end(); ++i) {
SourceOutputWidget* w = i->second;
+ if (sourceWidgets.size() > 1) {
+ w->directionLabel->show();
+ w->deviceButton->show();
+ } else {
+ w->directionLabel->hide();
+ w->deviceButton->hide();
+ }
+
if (showSourceOutputType == SOURCE_OUTPUT_ALL || w->type == showSourceOutputType) {
w->show();
is_empty = false;
@@ -848,7 +803,6 @@ void MainWindow::removeSink(uint32_t index) {
delete sinkWidgets[index];
sinkWidgets.erase(index);
- rebuildSinkCombo();
updateDeviceVisibility();
}
@@ -858,7 +812,6 @@ void MainWindow::removeSource(uint32_t index) {
delete sourceWidgets[index];
sourceWidgets.erase(index);
- rebuildSourceCombo();
updateDeviceVisibility();
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 48fcc76..a9f0f64 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -91,31 +91,8 @@ public:
Glib::ustring defaultSinkName, defaultSourceName;
- class DeviceColumns : public Gtk::TreeModel::ColumnRecord
- {
- public:
-
- DeviceColumns()
- { add(index); add(name); }
-
- Gtk::TreeModelColumn<uint32_t> index;
- Gtk::TreeModelColumn<Glib::ustring> name;
- };
-
- DeviceColumns deviceColumns;
-
- Glib::RefPtr<Gtk::ListStore> sinkTree;
- std::map<uint32_t, uint32_t> sinkTreeIndexes;
-
- Glib::RefPtr<Gtk::ListStore> sourceTree;
- std::map<uint32_t, uint32_t> sourceTreeIndexes;
-
protected:
virtual void on_realize();
-
-private:
- void rebuildSinkCombo();
- void rebuildSourceCombo();
};
diff --git a/src/pavucontrol.glade b/src/pavucontrol.glade
index 5f13333..07d1a36 100644
--- a/src/pavucontrol.glade
+++ b/src/pavucontrol.glade
@@ -498,7 +498,6 @@ Monitors</property>
<widget class="GtkImage" id="iconImage">
<property name="visible">True</property>
<property name="stock">gtk-missing-image</property>
- <property name="icon-size">4</property>
</widget>
<packing>
<property name="expand">False</property>
@@ -508,6 +507,7 @@ Monitors</property>
<child>
<widget class="GtkHBox" id="hbox12">
<property name="visible">True</property>
+ <property name="spacing">2</property>
<child>
<widget class="GtkLabel" id="boldNameLabel">
<property name="visible">True</property>
@@ -524,12 +524,42 @@ Monitors</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Stream Title</property>
<property name="use_markup">True</property>
- <property name="ellipsize">middle</property>
</widget>
<packing>
+ <property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <widget class="GtkLabel" id="directionLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">4</property>
+ <property name="label" translatable="yes">direction</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEventBox" id="deviceButton">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="deviceLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;a href=""&gt;Device&lt;/a&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="position">1</property>
@@ -582,6 +612,26 @@ Monitors</property>
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <widget class="GtkButton" id="terminateButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Terminate stream</property>
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-delete</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
@@ -612,52 +662,6 @@ Monitors</property>
<property name="position">1</property>
</packing>
</child>
- <child>
- <widget class="GtkHBox" id="streamControlHBox">
- <property name="visible">True</property>
- <child>
- <widget class="GtkLabel" id="directionLabel">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">direction</property>
- <property name="use_markup">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <widget class="GtkComboBox" id="deviceCombo">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <widget class="GtkButton" id="terminateButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip" translatable="yes">Terminate stream</property>
- <child>
- <widget class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="stock">gtk-delete</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
</widget>
<packing>
<property name="expand">False</property>
@@ -702,7 +706,6 @@ Monitors</property>
<widget class="GtkImage" id="iconImage">
<property name="visible">True</property>
<property name="stock">gtk-missing-image</property>
- <property name="icon-size">4</property>
</widget>
<packing>
<property name="expand">False</property>
@@ -947,7 +950,6 @@ Monitors</property>
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="stock">gtk-missing-image</property>
- <property name="icon-size">4</property>
</widget>
<packing>
<property name="expand">False</property>
diff --git a/src/rolewidget.cc b/src/rolewidget.cc
index 54c64d5..4da818f 100644
--- a/src/rolewidget.cc
+++ b/src/rolewidget.cc
@@ -32,7 +32,8 @@ RoleWidget::RoleWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade:
StreamWidget(cobject, x) {
lockToggleButton->hide();
- streamControlHBox->hide();
+ directionLabel->hide();
+ deviceButton->hide();
}
RoleWidget* RoleWidget::create() {
@@ -48,9 +49,6 @@ void RoleWidget::onMuteToggleButton() {
executeVolumeUpdate();
}
-void RoleWidget::onDeviceChange() {
-}
-
void RoleWidget::executeVolumeUpdate() {
pa_ext_stream_restore_info info;
diff --git a/src/rolewidget.h b/src/rolewidget.h
index 955364c..bbd39d6 100644
--- a/src/rolewidget.h
+++ b/src/rolewidget.h
@@ -33,7 +33,6 @@ public:
Glib::ustring role;
Glib::ustring device;
- virtual void onDeviceChange();
virtual void onMuteToggleButton();
virtual void executeVolumeUpdate();
};
diff --git a/src/sinkinputwidget.cc b/src/sinkinputwidget.cc
index 012e834..e5307b7 100644
--- a/src/sinkinputwidget.cc
+++ b/src/sinkinputwidget.cc
@@ -32,13 +32,13 @@ SinkInputWidget::SinkInputWidget(BaseObjectType* cobject, const Glib::RefPtr<Gno
StreamWidget(cobject, x),
mpMainWindow(NULL) {
- directionLabel->set_label(_("<i>Playing on </i> "));
+ gchar *txt;
+ directionLabel->set_label(txt = g_markup_printf_escaped("<i>%s</i>", _("on")));
+ g_free(txt);
}
void SinkInputWidget::init(MainWindow* mainWindow) {
mpMainWindow = mainWindow;
- deviceCombo->set_model(mpMainWindow->sinkTree);
- deviceCombo->pack_start(mpMainWindow->deviceColumns.name);
}
SinkInputWidget* SinkInputWidget::create(MainWindow* mainWindow) {
@@ -49,12 +49,22 @@ SinkInputWidget* SinkInputWidget::create(MainWindow* mainWindow) {
return w;
}
+SinkInputWidget::~SinkInputWidget(void) {
+ clearMenu();
+}
+
void SinkInputWidget::setSinkIndex(uint32_t idx) {
mSinkIndex = idx;
- mSuppressDeviceChange = true;
- deviceCombo->set_active(mpMainWindow->sinkTreeIndexes[idx]);
- mSuppressDeviceChange = false;
+ gchar *txt;
+ if (mpMainWindow->sinkWidgets.count(idx)) {
+ SinkWidget *w = mpMainWindow->sinkWidgets[idx];
+ txt = g_markup_printf_escaped("<a href=\"\">%s</a>", w->description.c_str());
+ }
+ else
+ txt = g_markup_printf_escaped("<a href=\"\">%s</a>", _("Unknown output"));
+ deviceLabel->set_label(txt);
+ g_free(txt);
}
uint32_t SinkInputWidget::sinkIndex() {
@@ -97,27 +107,50 @@ void SinkInputWidget::onKill() {
pa_operation_unref(o);
}
-void SinkInputWidget::onDeviceChange() {
- Gtk::TreeModel::iterator iter;
+void SinkInputWidget::clearMenu() {
+ while (!sinkMenuItems.empty()) {
+ std::map<uint32_t, SinkMenuItem*>::iterator i = sinkMenuItems.begin();
+ delete i->second;
+ sinkMenuItems.erase(i);
+ }
+}
- if (updating || mSuppressDeviceChange)
- return;
+void SinkInputWidget::buildMenu() {
+ for (std::map<uint32_t, SinkWidget*>::iterator i = mpMainWindow->sinkWidgets.begin(); i != mpMainWindow->sinkWidgets.end(); ++i) {
+ SinkMenuItem *m;
+ sinkMenuItems[i->second->index] = m = new SinkMenuItem(this, i->second->description.c_str(), i->second->index, i->second->index == mSinkIndex);
+ menu.append(m->menuItem);
+ }
+ menu.show_all();
+}
- iter = deviceCombo->get_active();
- if (iter)
- {
- Gtk::TreeModel::Row row = *iter;
- if (row)
- {
- pa_operation* o;
- uint32_t sink_index = row[mpMainWindow->deviceColumns.index];
-
- if (!(o = pa_context_move_sink_input_by_index(get_context(), index, sink_index, NULL, NULL))) {
- show_error(_("pa_context_move_sink_input_by_index() failed"));
- return;
- }
-
- pa_operation_unref(o);
- }
- }
+void SinkInputWidget::SinkMenuItem::onToggle() {
+ if (widget->updating)
+ return;
+
+ if (!menuItem.get_active())
+ return;
+
+ /*if (!mpMainWindow->sinkWidgets.count(widget->index))
+ return;*/
+
+ pa_operation* o;
+ if (!(o = pa_context_move_sink_input_by_index(get_context(), widget->index, index, NULL, NULL))) {
+ show_error(_("pa_context_move_sink_input_by_index() failed"));
+ return;
+ }
+
+ pa_operation_unref(o);
+}
+
+bool SinkInputWidget::onDeviceChangePopup(GdkEventButton* event) {
+ if (GDK_BUTTON_PRESS == event->type && 1 == event->button)
+ {
+ clearMenu();
+ buildMenu();
+ menu.popup(event->button, event->time);
+ return true;
+ }
+ else
+ return false;
}
diff --git a/src/sinkinputwidget.h b/src/sinkinputwidget.h
index 503c67c..b48a802 100644
--- a/src/sinkinputwidget.h
+++ b/src/sinkinputwidget.h
@@ -31,6 +31,7 @@ class SinkInputWidget : public StreamWidget {
public:
SinkInputWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x);
static SinkInputWidget* create(MainWindow* mainWindow);
+ ~SinkInputWidget(void);
void init(MainWindow* mainWindow);
@@ -40,7 +41,7 @@ public:
void setSinkIndex(uint32_t idx);
uint32_t sinkIndex();
virtual void executeVolumeUpdate();
- virtual void onDeviceChange();
+ virtual bool onDeviceChangePopup(GdkEventButton*);
virtual void onMuteToggleButton();
virtual void onKill();
@@ -48,6 +49,28 @@ private:
MainWindow *mpMainWindow;
uint32_t mSinkIndex;
+ void clearMenu();
+ void buildMenu();
+
+ Gtk::Menu menu;
+
+ struct SinkMenuItem {
+ SinkMenuItem(SinkInputWidget *w, const char *label, uint32_t i, bool active) :
+ widget(w),
+ menuItem(label),
+ index(i) {
+ menuItem.set_active(active);
+ menuItem.set_draw_as_radio(true);
+ menuItem.signal_toggled().connect(sigc::mem_fun(*this, &SinkMenuItem::onToggle));
+ }
+
+ SinkInputWidget *widget;
+ Gtk::CheckMenuItem menuItem;
+ uint32_t index;
+ void onToggle();
+ };
+
+ std::map<uint32_t, SinkMenuItem*> sinkMenuItems;
};
#endif
diff --git a/src/sourceoutputwidget.cc b/src/sourceoutputwidget.cc
index 19ecda7..fb3f441 100644
--- a/src/sourceoutputwidget.cc
+++ b/src/sourceoutputwidget.cc
@@ -32,13 +32,13 @@ SourceOutputWidget::SourceOutputWidget(BaseObjectType* cobject, const Glib::RefP
StreamWidget(cobject, x),
mpMainWindow(NULL) {
- directionLabel->set_label(_("<i>Recording from </i> "));
+ gchar *txt;
+ directionLabel->set_label(txt = g_markup_printf_escaped("<i>%s</i>", _("from")));
+ g_free(txt);
}
void SourceOutputWidget::init(MainWindow* mainWindow) {
mpMainWindow = mainWindow;
- deviceCombo->set_model(mpMainWindow->sourceTree);
- deviceCombo->pack_start(mpMainWindow->deviceColumns.name);
}
SourceOutputWidget* SourceOutputWidget::create(MainWindow* mainWindow) {
@@ -49,12 +49,22 @@ SourceOutputWidget* SourceOutputWidget::create(MainWindow* mainWindow) {
return w;
}
+SourceOutputWidget::~SourceOutputWidget(void) {
+ clearMenu();
+}
+
void SourceOutputWidget::setSourceIndex(uint32_t idx) {
mSourceIndex = idx;
- mSuppressDeviceChange = true;
- deviceCombo->set_active(mpMainWindow->sourceTreeIndexes[idx]);
- mSuppressDeviceChange = false;
+ gchar *txt;
+ if (mpMainWindow->sourceWidgets.count(idx)) {
+ SourceWidget *w = mpMainWindow->sourceWidgets[idx];
+ txt = g_markup_printf_escaped("<a href=\"\">%s</a>", w->description.c_str());
+ }
+ else
+ txt = g_markup_printf_escaped("<a href=\"\">%s</a>", _("Unknown input"));
+ deviceLabel->set_label(txt);
+ g_free(txt);
}
uint32_t SourceOutputWidget::sourceIndex() {
@@ -71,27 +81,51 @@ void SourceOutputWidget::onKill() {
pa_operation_unref(o);
}
-void SourceOutputWidget::onDeviceChange() {
- Gtk::TreeModel::iterator iter;
- if (updating || mSuppressDeviceChange)
- return;
+void SourceOutputWidget::clearMenu() {
+ while (!sourceMenuItems.empty()) {
+ std::map<uint32_t, SourceMenuItem*>::iterator i = sourceMenuItems.begin();
+ delete i->second;
+ sourceMenuItems.erase(i);
+ }
+}
+
+void SourceOutputWidget::buildMenu() {
+ for (std::map<uint32_t, SourceWidget*>::iterator i = mpMainWindow->sourceWidgets.begin(); i != mpMainWindow->sourceWidgets.end(); ++i) {
+ SourceMenuItem *m;
+ sourceMenuItems[i->second->index] = m = new SourceMenuItem(this, i->second->description.c_str(), i->second->index, i->second->index == mSourceIndex);
+ menu.append(m->menuItem);
+ }
+ menu.show_all();
+}
+
+void SourceOutputWidget::SourceMenuItem::onToggle() {
+ if (widget->updating)
+ return;
+
+ if (!menuItem.get_active())
+ return;
+
+ /*if (!mpMainWindow->sourceWidgets.count(widget->index))
+ return;*/
+
+ pa_operation* o;
+ if (!(o = pa_context_move_source_output_by_index(get_context(), widget->index, index, NULL, NULL))) {
+ show_error(_("pa_context_move_source_output_by_index() failed"));
+ return;
+ }
+
+ pa_operation_unref(o);
+}
- iter = deviceCombo->get_active();
- if (iter)
+bool SourceOutputWidget::onDeviceChangePopup(GdkEventButton* event) {
+ if (GDK_BUTTON_PRESS == event->type && 1 == event->button)
{
- Gtk::TreeModel::Row row = *iter;
- if (row)
- {
- pa_operation* o;
- uint32_t source_index = row[mpMainWindow->deviceColumns.index];
-
- if (!(o = pa_context_move_source_output_by_index(get_context(), source_index, index, NULL, NULL))) {
- show_error(_("pa_context_move_source_output_by_index() failed"));
- return;
- }
-
- pa_operation_unref(o);
- }
+ clearMenu();
+ buildMenu();
+ menu.popup(event->button, event->time);
+ return true;
}
+ else
+ return false;
}
diff --git a/src/sourceoutputwidget.h b/src/sourceoutputwidget.h
index 0d43cc9..ecf937f 100644
--- a/src/sourceoutputwidget.h
+++ b/src/sourceoutputwidget.h
@@ -31,6 +31,7 @@ class SourceOutputWidget : public StreamWidget {
public:
SourceOutputWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x);
static SourceOutputWidget* create(MainWindow* mainWindow);
+ ~SourceOutputWidget(void);
void init(MainWindow* mainWindow);
@@ -39,13 +40,35 @@ public:
uint32_t index, clientIndex;
void setSourceIndex(uint32_t idx);
uint32_t sourceIndex();
- virtual void onDeviceChange();
+ virtual bool onDeviceChangePopup(GdkEventButton*);
virtual void onKill();
private:
MainWindow *mpMainWindow;
uint32_t mSourceIndex;
+ void clearMenu();
+ void buildMenu();
+
+ Gtk::Menu menu;
+
+ struct SourceMenuItem {
+ SourceMenuItem(SourceOutputWidget *w, const char *label, uint32_t i, bool active) :
+ widget(w),
+ menuItem(label),
+ index(i) {
+ menuItem.set_active(active);
+ menuItem.set_draw_as_radio(true);
+ menuItem.signal_toggled().connect(sigc::mem_fun(*this, &SourceMenuItem::onToggle));
+ }
+
+ SourceOutputWidget *widget;
+ Gtk::CheckMenuItem menuItem;
+ uint32_t index;
+ void onToggle();
+ };
+
+ std::map<uint32_t, SourceMenuItem*> sourceMenuItems;
};
#endif
diff --git a/src/streamwidget.cc b/src/streamwidget.cc
index b739676..fd737fd 100644
--- a/src/streamwidget.cc
+++ b/src/streamwidget.cc
@@ -27,19 +27,18 @@
/*** StreamWidget ***/
StreamWidget::StreamWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x) :
- MinimalStreamWidget(cobject, x),
- mSuppressDeviceChange(false) {
+ MinimalStreamWidget(cobject, x) {
x->get_widget("lockToggleButton", lockToggleButton);
x->get_widget("muteToggleButton", muteToggleButton);
- x->get_widget("deviceCombo", deviceCombo);
x->get_widget("terminateButton", terminateButton);
x->get_widget("directionLabel", directionLabel);
- x->get_widget("streamControlHBox", streamControlHBox);
-
- deviceCombo->signal_changed().connect( sigc::mem_fun(*this, &StreamWidget::onDeviceChange));
+ x->get_widget("deviceButton", deviceButton);
+ x->get_widget("deviceLabel", deviceLabel);
+
terminateButton->signal_clicked().connect(sigc::mem_fun(*this, &StreamWidget::onKill));
muteToggleButton->signal_clicked().connect(sigc::mem_fun(*this, &StreamWidget::onMuteToggleButton));
+ deviceButton->signal_button_press_event().connect(sigc::mem_fun(*this, &StreamWidget::onDeviceChangePopup));
for (unsigned i = 0; i < PA_CHANNELS_MAX; i++)
channelWidgets[i] = NULL;
@@ -109,3 +108,7 @@ bool StreamWidget::timeoutEvent() {
void StreamWidget::executeVolumeUpdate() {
}
+
+bool StreamWidget::onDeviceChangePopup(GdkEventButton*) {
+ return false;
+}
diff --git a/src/streamwidget.h b/src/streamwidget.h
index 6dfb67c..48e3fd6 100644
--- a/src/streamwidget.h
+++ b/src/streamwidget.h
@@ -38,7 +38,8 @@ public:
Gtk::ToggleButton *lockToggleButton, *muteToggleButton;
Gtk::Button *terminateButton;
Gtk::Label *directionLabel;
- Gtk::HBox *streamControlHBox;
+ Gtk::EventBox *deviceButton;
+ Gtk::Label *deviceLabel;
pa_channel_map channelMap;
pa_cvolume volume;
@@ -46,7 +47,7 @@ public:
ChannelWidget *channelWidgets[PA_CHANNELS_MAX];
virtual void onMuteToggleButton();
- virtual void onDeviceChange() = 0;
+ virtual bool onDeviceChangePopup(GdkEventButton*);
virtual void onKill();
sigc::connection timeoutConnection;
@@ -54,11 +55,6 @@ public:
bool timeoutEvent();
virtual void executeVolumeUpdate();
-
-protected:
- Gtk::ComboBox *deviceCombo;
-
- bool mSuppressDeviceChange;
};
#endif