Add a new widget for the card configuration and use it.

This change allows the card profiles to be shown in a combo box. This is more natural and obvious
than hiding things in the submenu.
This commit is contained in:
Colin Guthrie 2009-02-28 19:51:08 +00:00
parent 1f1c8c8576
commit 6a76183326
2 changed files with 177 additions and 111 deletions

View File

@ -156,7 +156,6 @@ class CardWidget : public Gtk::VBox {
public: public:
CardWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x); CardWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x);
static CardWidget* create(); static CardWidget* create();
virtual ~CardWidget();
Gtk::Label *nameLabel, *boldNameLabel; Gtk::Label *nameLabel, *boldNameLabel;
Gtk::ToggleButton *streamToggleButton; Gtk::ToggleButton *streamToggleButton;
@ -166,43 +165,33 @@ public:
uint32_t index; uint32_t index;
bool updating; bool updating;
void onStreamToggleButton();
void onMenuDeactivated();
void popupMenuPosition(int& x, int& y, bool& push_in);
std::map<Glib::ustring,Glib::ustring> profiles; std::map<Glib::ustring,Glib::ustring> profiles;
Glib::ustring activeProfile; Glib::ustring activeProfile;
bool hasSinks; bool hasSinks;
bool hasSources; bool hasSources;
MainWindow *mainWindow; void prepareMenu();
Gtk::Menu submenu;
Gtk::MenuItem profilesMenuItem;
struct ProfileMenuItem {
ProfileMenuItem(CardWidget *w, const char *label, Glib::ustring profile, bool active) :
widget(w),
menuItem(label),
profile(profile) {
menuItem.set_active(active);
menuItem.set_draw_as_radio(true);
menuItem.signal_toggled().connect(sigc::mem_fun(*this, &ProfileMenuItem::onToggle));
}
CardWidget *widget;
Gtk::CheckMenuItem menuItem;
Glib::ustring profile;
void onToggle();
};
std::map<uint32_t, ProfileMenuItem*> profileMenuItems;
void clearMenu();
void buildMenu();
virtual void prepareMenu(void);
protected: protected:
virtual bool on_button_press_event(GdkEventButton* event); virtual void onProfileChange();
//Tree model columns:
class ModelColumns : public Gtk::TreeModel::ColumnRecord
{
public:
ModelColumns()
{ add(name); add(desc); }
Gtk::TreeModelColumn<Glib::ustring> name;
Gtk::TreeModelColumn<Glib::ustring> desc;
};
ModelColumns profileModel;
//Child widgets:
Gtk::ComboBox *profileList;
Glib::RefPtr<Gtk::ListStore> treeModel;
}; };
class SinkWidget : public StreamWidget { class SinkWidget : public StreamWidget {
@ -494,114 +483,72 @@ void ChannelWidget::set_sensitive(bool enabled) {
/*** CardWidget ***/ /*** CardWidget ***/
CardWidget::CardWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x) : CardWidget::CardWidget(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& x) :
Gtk::VBox(cobject), Gtk::VBox(cobject) {
profilesMenuItem(_("_Set Profile..."), true) {
x->get_widget("nameLabel", nameLabel); x->get_widget("nameLabel", nameLabel);
x->get_widget("boldNameLabel", boldNameLabel); x->get_widget("boldNameLabel", boldNameLabel);
x->get_widget("streamToggle", streamToggleButton); x->get_widget("profileList", profileList);
x->get_widget("iconImage", iconImage); x->get_widget("iconImage", iconImage);
streamToggleButton->set_active(false); profileList->signal_changed().connect( sigc::mem_fun(*this, &CardWidget::onProfileChange));
streamToggleButton->signal_clicked().connect(sigc::mem_fun(*this, &CardWidget::onStreamToggleButton));
menu.signal_deactivate().connect(sigc::mem_fun(*this, &CardWidget::onMenuDeactivated));
menu.append(profilesMenuItem);
profilesMenuItem.set_submenu(submenu);
}
CardWidget::~CardWidget() {
clearMenu();
} }
CardWidget* CardWidget::create() { CardWidget* CardWidget::create() {
CardWidget* w; CardWidget* w;
Glib::RefPtr<Gnome::Glade::Xml> x = Gnome::Glade::Xml::create(GLADE_FILE, "minimalStreamWidget"); Glib::RefPtr<Gnome::Glade::Xml> x = Gnome::Glade::Xml::create(GLADE_FILE, "cardWidget");
x->get_widget_derived("minimalStreamWidget", w); x->get_widget_derived("cardWidget", w);
return w; return w;
} }
void CardWidget::prepareMenu() { void CardWidget::prepareMenu() {
clearMenu(); int idx = 0;
buildMenu(); int active_idx = -1;
}
void CardWidget::clearMenu() { //m_refTreeModel = Gtk::TreeStore::create(m_Columns);
treeModel = Gtk::ListStore::create(profileModel);
profileList->set_model(treeModel);
while (!profileMenuItems.empty()) { //Fill the ComboBox's Tree Model:
std::map<uint32_t, ProfileMenuItem*>::iterator i = profileMenuItems.begin();
delete i->second;
profileMenuItems.erase(i);
}
}
void CardWidget::buildMenu() {
int num = 0;
for (std::map<Glib::ustring, Glib::ustring>::iterator i = profiles.begin(); i != profiles.end(); ++i) { for (std::map<Glib::ustring, Glib::ustring>::iterator i = profiles.begin(); i != profiles.end(); ++i) {
ProfileMenuItem *m; Gtk::TreeModel::Row row = *(treeModel->append());
profileMenuItems[num++] = m = new ProfileMenuItem(this, i->second.c_str(), i->first.c_str(), i->first == activeProfile); row[profileModel.name] = i->first;
submenu.append(m->menuItem); row[profileModel.desc] = i->second;
if (i->first == activeProfile)
active_idx = idx;
idx++;
} }
menu.show_all(); //Add the model columns to the Combo (which is a kind of view),
//rendering them in the default way:
profileList->pack_start(profileModel.desc);
if (active_idx >= 0)
profileList->set_active(active_idx);
} }
void CardWidget::ProfileMenuItem::onToggle() { void CardWidget::onProfileChange() {
Gtk::TreeModel::iterator iter;
if (widget->updating) if (updating)
return;
if (!menuItem.get_active())
return; return;
iter = profileList->get_active();
if (iter)
{
Gtk::TreeModel::Row row = *iter;
if (row)
{
pa_operation* o; pa_operation* o;
if (!(o = pa_context_set_card_profile_by_index(context, widget->index, profile.c_str(), NULL, NULL))) { Glib::ustring profile = row[profileModel.name];
if (!(o = pa_context_set_card_profile_by_index(context, index, profile.c_str(), NULL, NULL))) {
show_error(_("pa_context_set_card_profile_by_index() failed")); show_error(_("pa_context_set_card_profile_by_index() failed"));
return; return;
} }
pa_operation_unref(o); pa_operation_unref(o);
} }
void CardWidget::onMenuDeactivated(void) {
streamToggleButton->set_active(false);
} }
void CardWidget::popupMenuPosition(int& x, int& y, bool& push_in G_GNUC_UNUSED) {
Gtk::Requisition r;
streamToggleButton->get_window()->get_origin(x, y);
r = menu.size_request();
/* Align the right side of the menu with the right side of the togglebutton */
x += streamToggleButton->get_allocation().get_x();
x += streamToggleButton->get_allocation().get_width();
x -= r.width;
/* Align the top of the menu with the buttom of the togglebutton */
y += streamToggleButton->get_allocation().get_y();
y += streamToggleButton->get_allocation().get_height();
}
void CardWidget::onStreamToggleButton(void) {
if (streamToggleButton->get_active()) {
prepareMenu();
menu.popup(sigc::mem_fun(*this, &CardWidget::popupMenuPosition), 0, gtk_get_current_event_time());
}
}
bool CardWidget::on_button_press_event (GdkEventButton* event) {
if (Gtk::VBox::on_button_press_event(event))
return TRUE;
if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
prepareMenu();
menu.popup(0, event->time);
return TRUE;
}
return FALSE;
} }
@ -1218,6 +1165,8 @@ void MainWindow::updateCard(const pa_card_info &info) {
w->updating = false; w->updating = false;
w->prepareMenu();
if (is_new) if (is_new)
updateDeviceVisibility(); updateDeviceVisibility();
} }

View File

@ -810,4 +810,121 @@ Monitors</property>
</widget> </widget>
</child> </child>
</widget> </widget>
<widget class="GtkWindow" id="cardWindow">
<property name="visible">True</property>
<property name="title" translatable="yes">window1</property>
<child>
<widget class="GtkEventBox" id="cardWidget">
<property name="visible">True</property>
<child>
<widget class="GtkVBox" id="cardWidget1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<widget class="GtkVBox" id="vbox7">
<property name="visible">True</property>
<property name="border_width">12</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<widget class="GtkHBox" id="hbox9">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkImage" id="iconImage">
<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>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox11">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="boldNameLabel">
<property name="visible">True</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="nameLabel">
<property name="visible">True</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="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Profile</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="profileList">
<property name="visible">True</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator5">
<property name="visible">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</glade-interface> </glade-interface>