ardour
visibility_group.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 Paul Davis
3  Author: Carl Hetherington <cth@carlh.net>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 
19 */
20 
21 #include <gtkmm/menu.h>
22 #include <gtkmm/menushell.h>
23 #include <gtkmm/treeview.h>
24 #include "pbd/xml++.h"
25 #include "visibility_group.h"
26 
27 #include "i18n.h"
28 
29 using namespace std;
30 
32  : _xml_property_name (name)
33  , _ignore_list_view_change (false)
34 {
35 
36 }
37 
48 void
49 VisibilityGroup::add (Gtk::Widget* widget, string const & id, string const & name, bool visible, boost::function<boost::optional<bool> ()> override)
50 {
51  Member m;
52  m.widget = widget;
53  m.id = id;
54  m.name = name;
55  m.visible = visible;
56  m.override = override;
57 
58  _members.push_back (m);
59 }
60 
62 bool
64 {
65  if (ev->button != 3) {
66  return false;
67  }
68 
69  menu()->popup (1, ev->time);
70  return true;
71 }
72 
73 Gtk::Menu*
75 {
76  using namespace Gtk::Menu_Helpers;
77 
78  Gtk::Menu* m = Gtk::manage (new Gtk::Menu);
79  MenuList& items = m->items ();
80 
81  for (vector<Member>::iterator i = _members.begin(); i != _members.end(); ++i) {
82  items.push_back (CheckMenuElem (i->name));
83  Gtk::CheckMenuItem* j = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
84  j->set_active (i->visible);
85  j->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &VisibilityGroup::toggle), i));
86  }
87 
88  return m;
89 }
90 
92 bool
94 {
95  if (m.override) {
96  boost::optional<bool> o = m.override ();
97  if (o) {
98  return o.get ();
99  }
100  }
101 
102  return m.visible;
103 }
104 
106 void
108 {
109  for (vector<Member>::iterator i = _members.begin(); i != _members.end(); ++i) {
110  if (i->widget) {
111  if (should_actually_be_visible (*i)) {
112  i->widget->show ();
113  } else {
114  i->widget->hide ();
115  }
116  }
117  }
118 
119  update_list_view ();
120 
121  VisibilityChanged (); /* EMIT SIGNAL */
122 }
123 
124 void
125 VisibilityGroup::toggle (vector<Member>::iterator m)
126 {
127  m->visible = !m->visible;
128  update ();
129 }
130 
131 void
133 {
134  XMLProperty const * p = node.property (_xml_property_name);
135  if (!p) {
136  return;
137  }
138 
139  set_state (p->value ());
140 }
141 
142 void
144 {
145  for (vector<Member>::iterator i = _members.begin(); i != _members.end(); ++i) {
146  i->visible = false;
147  }
148 
149  do {
150  string::size_type const comma = v.find_first_of (',');
151  string segment = v.substr (0, comma);
152 
153  for (vector<Member>::iterator i = _members.begin(); i != _members.end(); ++i) {
154  if (segment == i->id) {
155  i->visible = true;
156  }
157  }
158 
159  if (comma == string::npos) {
160  break;
161  }
162 
163  v = v.substr (comma + 1);
164 
165  } while (1);
166 
167  update ();
168 }
169 
170 string
172 {
173  return _xml_property_name;
174 }
175 
176 string
178 {
179  string result;
180  for (vector<Member>::const_iterator i = _members.begin(); i != _members.end(); ++i) {
181  if (i->visible) {
182  if (!result.empty ()) {
183  result += ',';
184  }
185  result += i->id;
186  }
187  }
188 
189  return result;
190 }
191 
192 void
194 {
195  if (!_model) {
196  return;
197  }
198 
200 
201  _model->clear ();
202 
203  for (vector<Member>::iterator i = _members.begin(); i != _members.end(); ++i) {
204  Gtk::TreeModel::iterator j = _model->append ();
205  Gtk::TreeModel::Row row = *j;
206  row[_model_columns._visible] = i->visible;
207  row[_model_columns._name] = i->name;
208  row[_model_columns._iterator] = i;
209  }
210 
211  _ignore_list_view_change = false;
212 }
213 
214 Gtk::Widget *
216 {
217  _model = Gtk::ListStore::create (_model_columns);
218 
219  update_list_view ();
220 
221  Gtk::TreeView* v = Gtk::manage (new Gtk::TreeView (_model));
222  v->set_headers_visible (false);
223  v->append_column ("", _model_columns._visible);
224  v->append_column ("", _model_columns._name);
225 
226  Gtk::CellRendererToggle* visible_cell = dynamic_cast<Gtk::CellRendererToggle*> (v->get_column_cell_renderer (0));
227  visible_cell->property_activatable() = true;
228  visible_cell->signal_toggled().connect (sigc::mem_fun (*this, &VisibilityGroup::list_view_visible_changed));
229  return v;
230 }
231 
232 void
234 {
236  return;
237  }
238 
239  Gtk::TreeModel::iterator i = _model->get_iter (path);
240  if (!i) {
241  return;
242  }
243 
244  vector<Member>::iterator j = (*i)[_model_columns._iterator];
245  j->visible = !j->visible;
246  (*i)[_model_columns._visible] = j->visible;
247 
248  update ();
249 }
void set_state(XMLNode const &)
Gtk::TreeModelColumn< std::string > _name
const std::string & value() const
Definition: xml++.h:159
std::vector< Member > _members
Gtk::Menu * menu()
bool button_press_event(GdkEventButton *)
Definition: Beats.hpp:239
std::string _xml_property_name
bool should_actually_be_visible(Member const &) const
PBD::Signal0< void > VisibilityChanged
XMLProperty * property(const char *)
Definition: xml++.cc:413
Gtk::TreeModelColumn< std::vector< Member >::iterator > _iterator
Gtk::Widget * list_view()
std::string get_state_value() const
const char * name
boost::function< boost::optional< bool >)> override
Definition: xml++.h:95
Gtk::TreeModelColumn< bool > _visible
void add(Gtk::Widget *, std::string const &, std::string const &, bool visible=false, boost::function< boost::optional< bool >()>=0)
Glib::RefPtr< Gtk::ListStore > _model
void list_view_visible_changed(std::string const &)
ModelColumns _model_columns
VisibilityGroup(std::string const &)
void toggle(std::vector< Member >::iterator)
std::string get_state_name() const