1 /*
2 * Copyright (C) 2017 Hermann Meyer, Andreas Degert
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 * --------------------------------------------------------------------------
18 */
19
20 #include "guitarix.h" // NOLINT
21
22 namespace gx_seq {
23
24 #define DRUMS 6
25
26 #define FOR_DRUMS(func) std::for_each(drums.begin(), drums.end(), [&](Drums d) { func });
27
28 /****************************************************************
29 ** PluginPresetConnectWindow
30 */
31
create_from_builder(BaseObjectType * cobject,Glib::RefPtr<gx_gui::GxBuilder> bld,gx_engine::GxMachineBase & _machine)32 PluginPresetConnectWindow *PluginPresetConnectWindow::create_from_builder(
33 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld, gx_engine::GxMachineBase& _machine) {
34 return new PluginPresetConnectWindow(cobject, bld, _machine);
35 }
36
~PluginPresetConnectWindow()37 PluginPresetConnectWindow::~PluginPresetConnectWindow() {
38 }
39
create(gx_engine::GxMachineBase & machine)40 PluginPresetConnectWindow *PluginPresetConnectWindow::create(
41 gx_engine::GxMachineBase& machine) {
42 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(
43 machine.get_options().get_builder_filepath("pluginpreset_connectwindow.glade"));
44 PluginPresetConnectWindow *w;
45 bld->get_toplevel_derived("PluginPresetConnectWindow", w,
46 sigc::bind(sigc::ptr_fun(PluginPresetConnectWindow::create_from_builder), bld, sigc::ref(machine)));
47 return w;
48 }
49
on_key_press_event(GdkEventKey * event)50 bool PluginPresetConnectWindow::on_key_press_event(GdkEventKey *event) {
51 if (event->keyval == GDK_KEY_Escape && (event->state & Gtk::AccelGroup::get_default_mod_mask()) == 0) {
52 hide();
53 return true;
54 }
55 return Gtk::Window::on_key_press_event(event);
56 }
57
on_connect()58 void PluginPresetConnectWindow::on_connect() {
59 Gtk::TreeIter it = treeview->get_selection()->get_selected();
60 if (it && !machine.midi_get_config_mode()) {
61 Glib::ustring id = "seq." + it->get_value(upresetliststore->col.name);
62 if (machine.parameter_hasId(id))
63 new gx_main_midi::MidiConnect(0, machine.get_parameter(id), machine);
64 }
65 }
66
PluginPresetConnectWindow(BaseObjectType * cobject,Glib::RefPtr<gx_gui::GxBuilder> bld,gx_engine::GxMachineBase & _machine)67 PluginPresetConnectWindow::PluginPresetConnectWindow(
68 BaseObjectType* cobject, Glib::RefPtr<gx_gui::GxBuilder> bld, gx_engine::GxMachineBase& _machine)
69 : Gtk::Window(cobject),
70 upresetliststore(UPresetListStore::create()),
71 machine(_machine) {
72 set_title("Connect Midi");
73 Gtk::Button *b;
74 bld->find_widget("closebutton", b);
75 b->signal_clicked().connect(
76 sigc::mem_fun(*this, &PluginPresetConnectWindow::hide));
77 bld->find_widget("connectbutton", connectbutton);
78 connectbutton->signal_clicked().connect(
79 sigc::mem_fun0(*this, &PluginPresetConnectWindow::on_connect));
80 bld->find_widget("treeview", treeview);
81 gx_preset::UnitPresetList presetnames;
82 machine.plugin_preset_list_load(machine.pluginlist_lookup_plugin("seq")->get_pdef(), presetnames);
83 for (gx_preset::UnitPresetList::const_iterator i = presetnames.begin(); i != presetnames.end(); ++i) {
84 if (i->name.empty()) {
85 break;
86 }
87 upresetliststore->append()->set_value(upresetliststore->col.name, i->name);
88 }
89 treeview->set_model(upresetliststore);
90 connectbutton->set_sensitive(false);
91 Glib::RefPtr<Gtk::TreeSelection> sel = treeview->get_selection();
92 sel->signal_changed().connect(
93 sigc::mem_fun(*this, &PluginPresetConnectWindow::on_selection_changed));
94 }
95
on_selection_changed()96 void PluginPresetConnectWindow::on_selection_changed() {
97 connectbutton->set_sensitive(treeview->get_selection()->get_selected());
98 }
99
run()100 void PluginPresetConnectWindow::run() {
101 Gtk::Main::run(*this);
102 }
103
104 /****************************************************************
105 ** Sequencer Parameter Window
106 */
107
create(const std::string & unit_id,gx_engine::GxMachineBase & machine)108 SEQWindow *SEQWindow::create(const std::string& unit_id, gx_engine::GxMachineBase& machine) {
109 Glib::RefPtr<gx_gui::GxBuilder> bld = gx_gui::GxBuilder::create_from_file(
110 machine.get_options().get_builder_filepath("Sequencer.glade"), &machine);
111 gx_engine::SeqParameter *tomp = dynamic_cast<gx_engine::SeqParameter*>(&machine.get_parameter("seq.sequencer.tom"));
112 gx_engine::SeqParameter *tomp1 = dynamic_cast<gx_engine::SeqParameter*>(&machine.get_parameter("seq.sequencer.tom1"));
113 gx_engine::SeqParameter *tomp2 = dynamic_cast<gx_engine::SeqParameter*>(&machine.get_parameter("seq.sequencer.tom2"));
114 gx_engine::SeqParameter *kickp = dynamic_cast<gx_engine::SeqParameter*>(&machine.get_parameter("seq.sequencer.kick"));
115 gx_engine::SeqParameter *snarep = dynamic_cast<gx_engine::SeqParameter*>(&machine.get_parameter("seq.sequencer.snare"));
116 gx_engine::SeqParameter *hatp = dynamic_cast<gx_engine::SeqParameter*>(&machine.get_parameter("seq.sequencer.hat"));
117 assert(tomp);
118 assert(tomp1);
119 assert(tomp2);
120 assert(kickp);
121 assert(snarep);
122 assert(hatp);
123 return new SEQWindow(bld, tomp, tomp1, tomp2, kickp, snarep, hatp, machine);
124 }
125
126 /*
127 ** Constructor
128 */
129
SEQWindow(const Glib::RefPtr<gx_gui::GxBuilder> & bld,gx_engine::SeqParameter * tomp_,gx_engine::SeqParameter * tomp1_,gx_engine::SeqParameter * tomp2_,gx_engine::SeqParameter * kickp_,gx_engine::SeqParameter * snarep_,gx_engine::SeqParameter * hatp_,gx_engine::GxMachineBase & machine_)130 SEQWindow::SEQWindow(const Glib::RefPtr<gx_gui::GxBuilder>& bld,gx_engine::SeqParameter *tomp_,
131 gx_engine::SeqParameter *tomp1_,gx_engine::SeqParameter *tomp2_,
132 gx_engine::SeqParameter *kickp_, gx_engine::SeqParameter *snarep_,
133 gx_engine::SeqParameter *hatp_, gx_engine::GxMachineBase& machine_)
134 : machine(machine_),
135 builder(bld),
136 tom(tomp_),
137 tom1(tomp1_),
138 tom2(tomp2_),
139 kick(kickp_),
140 snare(snarep_),
141 hat(hatp_),
142 is_active(false),
143 gtk_window(0) {
144 bld->get_toplevel("SequencerWindow", gtk_window);
145
146 init_connect();
147
148 // reset display
149 }
150
init_connect()151 void SEQWindow::init_connect() {
152
153 builder->find_widget("viewport1", vp);
154 builder->find_widget("hbox1", tom.box);
155 builder->find_widget("hbox1a", tom1.box);
156 builder->find_widget("hbox1b", tom2.box);
157 builder->find_widget("hbox2", kick.box);
158 builder->find_widget("hbox3", snare.box);
159 builder->find_widget("hbox4", hat.box);
160 builder->find_widget("gxplayhead1", seq_pos);
161 builder->find_widget("gxsmallknob6", seq_count);
162 builder->find_widget("gxselector1", seq_tact);
163 builder->find_widget("hbox12", preset_button);
164 builder->find_widget("gxswitch6", add_button);
165 builder->find_widget("gxswitch3", next_preset);
166 builder->find_widget("gxswitch7", previus_preset);
167 builder->find_widget("gxswitch4", set_step);
168 builder->find_widget("gxswitch5", set_fstep);
169 builder->find_widget("gxswitch8", set_sync);
170 builder->find_widget("gxswitch9", reset_step);
171 builder->find_widget("label9:rack_label_inverse", preset_label);
172 builder->find_widget("gxvaluedisplay1", step_value);
173 builder->find_widget("label8:rack_label_inverse", step_label);
174
175 Pango::FontDescription font = preset_label->get_style_context()->get_font();
176 font.set_size(10*Pango::SCALE);
177 font.set_weight(Pango::WEIGHT_BOLD);
178 preset_label->override_font(font);
179
180 make_preset_button(preset_button);
181
182 drums.push_back(tom);
183 drums.push_back(tom1);
184 drums.push_back(tom2);
185 drums.push_back(kick);
186 drums.push_back(snare);
187 drums.push_back(hat);
188
189 on_sec_length_changed(false);
190
191 FOR_DRUMS(
192 d.p->signal_changed().connect(sigc::bind(
193 sigc::mem_fun(this, &SEQWindow::seq_changed), d.box));
194 init_sequences(d.p, d.box);
195 );
196
197 seq_pos->cp_set_value(0.0);
198 std::string id;
199 seq_pos->get_property("var_id",id);
200
201 int ti_o = 60;
202 if (!machine.get_jack()) ti_o = 250;
203 Glib::signal_timeout().connect(
204 sigc::bind<Gxw::Regler*>(sigc::bind<const std::string>(
205 sigc::mem_fun(*this, &SEQWindow::get_sequencer_pos),id), seq_pos), ti_o);
206
207 seq_count->signal_value_changed().connect(
208 sigc::bind(sigc::mem_fun(*this, &SEQWindow::on_sec_length_changed), true));
209
210 seq_tact->signal_value_changed().connect(
211 sigc::mem_fun(*this, &SEQWindow::on_sec_tact_changed));
212
213 next_preset->signal_toggled().connect(
214 sigc::mem_fun(*this, &SEQWindow::on_next_preset));
215
216 previus_preset->signal_toggled().connect(
217 sigc::mem_fun(*this, &SEQWindow::on_previus_preset));
218
219 set_step->signal_toggled().connect(
220 sigc::mem_fun(*this, &SEQWindow::on_set_step));
221
222 set_fstep->signal_toggled().connect(
223 sigc::mem_fun(*this, &SEQWindow::on_set_fstep));
224
225 set_sync->signal_toggled().connect(
226 sigc::mem_fun(*this, &SEQWindow::on_sync_stepper));
227
228 reset_step->signal_toggled().connect(
229 sigc::mem_fun(*this, &SEQWindow::on_reset_stepper));
230
231 add_button->signal_clicked().connect(
232 sigc::mem_fun(*this, &SEQWindow::on_preset_add_clicked));
233 gx_gui::GxBuilder::set_tooltip_text_connect_handler(*add_button, _("add effect unit preset to the sequence"));
234
235 gtk_window->signal_key_press_event().connect(
236 sigc::mem_fun(this, &SEQWindow::on_key_press_event));
237
238 if (!machine.get_jack()) {
239 step_value->hide();
240 step_label->hide();
241 }
242 }
243
init_sequences(gx_engine::SeqParameter * p,Gtk::Box * _box)244 void SEQWindow::init_sequences(gx_engine::SeqParameter *p, Gtk::Box* _box) {
245 Glib::ListHandle<Gtk::Widget*> List = _box->get_children();
246 for (Glib::ListHandle<Gtk::Widget*>::iterator itt = List.begin();itt != List.end(); ++itt) {
247 dynamic_cast<Gtk::ToggleButton*>((*itt))->signal_clicked().connect(
248 sigc::bind(sigc::bind(sigc::mem_fun(this, &SEQWindow::on_seq_button_clicked),p),_box));
249 }
250 }
251
on_set_step()252 void SEQWindow::on_set_step() {
253 if (!set_step->get_active()) return;
254 float tactv = machine.get_parameter_value<float>("seq.tact");
255 float value = std::max(0,int(machine.get_parameter_value<float>("seq.step")-tactv));
256 reset_control("seq.step",value);
257 set_step->set_active(false);
258 }
259
on_set_fstep()260 void SEQWindow::on_set_fstep() {
261 if (!set_fstep->get_active()) return;
262 float tactv = machine.get_parameter_value<float>("seq.tact");
263 float valuea = machine.get_parameter_value<float>("seq.asequences");
264 float value = std::min(int(valuea),int(machine.get_parameter_value<float>("seq.step")+tactv));
265 reset_control("seq.step",value);
266 set_fstep->set_active(false);
267 }
268
on_sync_stepper()269 void SEQWindow::on_sync_stepper() {
270 if (!set_sync->get_active()) return;
271 reset_control("seq.step",machine.get_parameter_value<float>("seq.step_orig"));
272 set_sync->set_active(false);
273 }
274
on_reset_stepper()275 void SEQWindow::on_reset_stepper() {
276 if (!reset_step->get_active()) return;
277 reset_control("seq.step",0.0);
278 reset_control("seq.step_orig",0.0);
279 reset_control("seq.pos",0.0);
280 reset_step->set_active(false);
281 }
282
on_next_preset()283 void SEQWindow::on_next_preset() {
284 if (!next_preset->get_active()) return;
285 if (!is_active) {
286 is_active = true;
287 Glib::signal_idle().connect_once(sigc::mem_fun(this, &SEQWindow::on_next_preset_set));
288 }
289 }
290
on_next_preset_set()291 void SEQWindow::on_next_preset_set() {
292 gx_preset::UnitPresetList presetnames;
293 machine.plugin_preset_list_load(machine.pluginlist_lookup_plugin("seq")->get_pdef(), presetnames);
294 for (gx_preset::UnitPresetList::iterator i = presetnames.begin(); i != presetnames.end(); ++i) {
295 if (!i->name.empty()) {
296 if (i->is_set) {
297 ++i;
298 if (i->name.empty()) i = presetnames.begin();
299 machine.plugin_preset_list_sync_set(machine.pluginlist_lookup_plugin("seq")->get_pdef(), false, i->name);
300 break;
301 } else {
302 machine.plugin_preset_list_sync_set(machine.pluginlist_lookup_plugin("seq")->get_pdef(), false, presetnames.begin()->name);
303 }
304 }
305 }
306 is_active = false;
307 reset_control("seq.npreset",0);
308 }
309
on_previus_preset()310 void SEQWindow::on_previus_preset() {
311 if (!previus_preset->get_active()) return;
312 if (!is_active) {
313 is_active = true;
314 Glib::signal_idle().connect_once(sigc::mem_fun(this, &SEQWindow::on_previus_preset_set));
315 }
316 }
317
on_previus_preset_set()318 void SEQWindow::on_previus_preset_set() {
319 gx_preset::UnitPresetList presetnames;
320 machine.plugin_preset_list_load(machine.pluginlist_lookup_plugin("seq")->get_pdef(), presetnames);
321 gx_preset::UnitPresetList::iterator i = presetnames.begin();
322 for ( i = presetnames.begin(); i != presetnames.end(); ++i) {
323 if (!i->name.empty()) {
324 if (i->is_set) break;
325 }
326 }
327 if (i == presetnames.begin()) {
328 i = presetnames.end();
329 --i;
330 } else if (i == presetnames.end()) {
331 i -=2;
332 }
333 --i;
334 machine.plugin_preset_list_sync_set(machine.pluginlist_lookup_plugin("seq")->get_pdef(), false, i->name);
335 is_active = false;
336 reset_control("seq.ppreset",0);
337 }
338
on_preset_popup_clicked()339 void SEQWindow::on_preset_popup_clicked() {
340 Gtk::Menu *presetMenu = static_cast<Gtk::Menu*>(new PluginPresetPopup(machine.pluginlist_lookup_plugin("seq")->get_pdef(), machine));
341 Gtk::MenuItem* subitem = Gtk::manage(new Gtk::MenuItem("connect midi...", true));
342 presetMenu->append(*subitem);
343 subitem->signal_activate().connect(sigc::mem_fun(
344 *this, &SEQWindow::connect_midi));
345 presetMenu->show_all();
346 }
347
connect_midi()348 void SEQWindow::connect_midi() {
349 PluginPresetConnectWindow *w = PluginPresetConnectWindow::create(machine);
350 w->run();
351 delete w;
352 }
353
make_preset_button(Gtk::Box * box)354 void SEQWindow::make_preset_button(Gtk::Box * box) {
355 Gtk::Button *p = new Gtk::Button();
356 Gtk::Image *l = new Gtk::Image();
357 l->Gtk::Image::set_from_icon_name("rack_preset", Gtk::ICON_SIZE_BUTTON);
358 p->add(*Gtk::manage(l));
359 p->set_can_default(false);
360 p->set_can_focus(false);
361 gx_gui::GxBuilder::set_tooltip_text_connect_handler(*p, _("manage effect unit presets"));
362 p->set_name("effect_on_off");
363 box->pack_start(*Gtk::manage(p),Gtk::PACK_SHRINK);
364 p->signal_clicked().connect(
365 sigc::mem_fun(*this, &SEQWindow::on_preset_popup_clicked));
366 p->show_all();
367 }
368
reset_control(Glib::ustring id,float value)369 void SEQWindow::reset_control(Glib::ustring id, float value) {
370 machine.set_parameter_value(id,value);
371 machine.signal_parameter_value<float>(id)(value);
372 }
373
append_sequence(const gx_engine::GxSeqSettings * seqc,gx_engine::SeqParameter * p,std::vector<int> * sequence)374 int SEQWindow::append_sequence(const gx_engine::GxSeqSettings* seqc, gx_engine::SeqParameter *p, std::vector<int> *sequence) {
375 int s = 0;
376 std::vector<int> sequence_append = seqc->getseqline();
377 for(std::vector<int>::const_iterator i = sequence_append.begin(); i != sequence_append.end(); ++i) {
378 sequence->push_back(*i);
379 ++s;
380 }
381 return s;
382 }
383
append_plugin_preset(Glib::ustring name)384 void SEQWindow::append_plugin_preset(Glib::ustring name) {
385 if (!is_active) {
386 is_active = true;
387 Glib::signal_timeout().connect_once(sigc::bind(sigc::mem_fun(this, &SEQWindow::append_plugin_preset_set),name),5);
388 }
389 }
390
append_plugin_preset_set(Glib::ustring name)391 void SEQWindow::append_plugin_preset_set(Glib::ustring name) {
392 // get current sequences
393 std::vector<int> sequence[DRUMS];
394 int i = 0;
395 FOR_DRUMS(
396 sequence[i] = static_cast<const gx_engine::GxSeqSettings*>(&d.p->get_value())->getseqline();
397 ++i;
398 );
399
400 // get current control values
401 float value = machine.get_parameter_value<float>("seq.asequences");
402 float bpmv = machine.get_parameter_value<float>("seq.bpm");
403 float tactv = machine.get_parameter_value<float>("seq.tact");
404 float gainv = machine.get_parameter_value<float>("seq.gain");
405 float tomg = machine.get_parameter_value<float>("seq.tom.dsp.Gain");
406 float tomg1 = machine.get_parameter_value<float>("seq.tom.dsp.Gain1");
407 float tomg2 = machine.get_parameter_value<float>("seq.tom.dsp.Gain2");
408 float kickg = machine.get_parameter_value<float>("seq.kick.dsp.Gain");
409 float snareg = machine.get_parameter_value<float>("seq.snare.dsp.Gain");
410 float hatg = machine.get_parameter_value<float>("seq.hat_closed.dsp.Gain");
411 // set preset values
412 machine.plugin_preset_list_set(machine.pluginlist_lookup_plugin("seq")->get_pdef(), false, name);
413
414 // append preset sequence to current and get new step size
415 int s = 24;
416 i = 0;
417 FOR_DRUMS(
418 s = append_sequence(&d.p->get_value(), d.p, &sequence[i]);
419 ++i;
420 );
421
422 // set new step size
423 value += float(s);
424 reset_control("seq.asequences",value);
425
426 // set new sequences as parameter
427 gx_engine::GxSeqSettings seqc;
428 i = 0;
429 FOR_DRUMS(
430 seqc.setseqline(sequence[i]);
431 d.p->set(seqc);
432 ++i;
433 );
434
435 // reset controls to previous values
436 reset_control("seq.bpm",bpmv);
437 reset_control("seq.tact",tactv);
438 reset_control("seq.gain",gainv);
439 reset_control("seq.tom.dsp.Gain",tomg);
440 reset_control("seq.tom.dsp.Gain1",tomg1);
441 reset_control("seq.tom.dsp.Gain2",tomg2);
442 reset_control("seq.kick.dsp.Gain",kickg);
443 reset_control("seq.snare.dsp.Gain",snareg);
444 reset_control("seq.hat_closed.dsp.Gain",hatg);
445
446 is_active = false;
447 }
448
delete_plugin_preset_popup(Gtk::Menu * presetMenu)449 static bool delete_plugin_preset_popup(Gtk::Menu *presetMenu) {
450 delete presetMenu;
451 return false;
452 }
453
on_selection_done(Gtk::Menu * presetMenu)454 void SEQWindow::on_selection_done(Gtk::Menu *presetMenu) {
455 Glib::signal_idle().connect(sigc::bind(
456 sigc::ptr_fun(delete_plugin_preset_popup), presetMenu));
457 }
458
on_preset_add_clicked()459 void SEQWindow::on_preset_add_clicked() {
460 if (!add_button->get_active()) return;
461 Gtk::MenuItem* item;
462 Gtk::Menu *presetMenu = Gtk::manage(new Gtk::Menu());
463 gx_preset::UnitPresetList presetnames;
464 machine.plugin_preset_list_load(machine.pluginlist_lookup_plugin("seq")->get_pdef(), presetnames);
465 for (gx_preset::UnitPresetList::iterator i = presetnames.begin(); i != presetnames.end(); ++i) {
466 if (!i->name.empty()) {
467 item = Gtk::manage(new Gtk::MenuItem(i->name, true));
468 presetMenu->append(*item);
469 item->signal_activate().connect(sigc::bind(sigc::mem_fun(
470 *this, &SEQWindow::append_plugin_preset),i->name));
471 }
472 }
473 presetMenu->signal_selection_done().connect(sigc::bind(sigc::mem_fun(
474 *this, &SEQWindow::on_selection_done),presetMenu));
475 presetMenu->show_all();
476 presetMenu->popup(1, gtk_get_current_event_time());
477 add_button->set_active(false);
478 }
479
on_sec_length_changed(bool update)480 void SEQWindow::on_sec_length_changed(bool update) {
481 static int r_save = 24;
482 int r = int(seq_count->cp_get_value());
483 if ( r_save > r) {
484 FOR_DRUMS(
485 remove_seq_block(d.box, r);
486 );
487 r_save = r;
488 } else if( r_save < r) {
489 FOR_DRUMS(
490 append_seq_block(d.box,d.p, r,r_save);
491 );
492 r_save = r;
493 }
494 if (update) {
495 FOR_DRUMS(
496 on_seq_button_clicked(d.box,d.p);
497 );
498 }
499 }
500
on_sec_tact_changed()501 void SEQWindow::on_sec_tact_changed() {
502 FOR_DRUMS(
503 seq_changed(&d.p->get_value(), d.box);
504 );
505 }
506
append_seq_block(Gtk::Box * box,gx_engine::SeqParameter * p,int r,int r_save)507 void SEQWindow::append_seq_block(Gtk::Box * box, gx_engine::SeqParameter *p, int r, int r_save) {
508 Gtk::ToggleButton * ab;
509 for(int j = r_save; j<r; ++j) {
510 ab = new Gtk::ToggleButton();
511 box->pack_start(*Gtk::manage(ab),Gtk::PACK_EXPAND_WIDGET);
512 ab->signal_clicked().connect(
513 sigc::bind(sigc::bind(sigc::mem_fun(this, &SEQWindow::on_seq_button_clicked),p),box));
514 ab->show();
515 }
516 }
517
remove_seq_block(Gtk::Box * box,int r)518 void SEQWindow::remove_seq_block(Gtk::Box * box, int r) {
519 Glib::ListHandle<Gtk::Widget*> boxList = box->get_children();
520 int i = 0;
521 for (Glib::ListHandle<Gtk::Widget*>::iterator itt = boxList.begin();itt != boxList.end(); ++itt) {
522 if (i>=r) {
523 box->remove(*(*itt));
524 delete((*itt));
525 }
526 ++i;
527 }
528 }
529
scroll_playhead(float value)530 void SEQWindow::scroll_playhead(float value) {
531 Glib::RefPtr<Gtk::Adjustment> a = vp->get_hadjustment();
532 static float old_state = 0.0;
533 float u = a->get_upper();
534 float l = a->get_lower();
535 float s = a->get_page_size();
536 float set = (u-s) * ((value)/2300.0);
537 if (u>s) {
538 if (set>l && set<u) {
539 if(std::abs(set-old_state) > 10) {
540 a->set_value(set);
541 old_state = set;
542 }
543 }
544 }
545
546 }
547
get_sequencer_pos(Gxw::Regler * regler,const std::string id)548 bool SEQWindow::get_sequencer_pos(Gxw::Regler * regler, const std::string id) {
549 float value = 0;
550 if (machine.parameter_hasId(id)) {
551 if (machine.get_parameter_value<bool>(id.substr(0,id.find_last_of(".")+1)+"on_off")) {
552 value = machine.get_parameter_value<float>(id);
553 if (!machine.get_jack()) {
554 if (value<99.0) return true;
555 }
556 machine.signal_parameter_value<float>(id)(value);
557 if (machine.get_jack()) machine.signal_parameter_value<float>("seq.step")(machine.get_parameter_value<float>("seq.step"));
558 if (machine.get_parameter_value<float>("seq.follow"))
559 scroll_playhead(value);
560 }
561 return gtk_window->get_visible();
562 } else {
563 return false;
564 }
565 }
566
on_key_press_event(GdkEventKey * event)567 bool SEQWindow::on_key_press_event(GdkEventKey *event) {
568 return true;
569 }
570
on_seq_button_clicked(Gtk::Box * box,gx_engine::SeqParameter * p)571 void SEQWindow::on_seq_button_clicked(Gtk::Box *box, gx_engine::SeqParameter *p) {
572 Glib::signal_timeout().connect_once(sigc::bind(sigc::bind(sigc::mem_fun(this, &SEQWindow::on_seq_button_clicked_set),p),box),2);
573 }
574
on_seq_button_clicked_set(Gtk::Box * box,gx_engine::SeqParameter * p)575 void SEQWindow::on_seq_button_clicked_set(Gtk::Box *box, gx_engine::SeqParameter *p) {
576 std::vector<int> sequence;
577 gx_engine::GxSeqSettings seqc;
578 Glib::ListHandle<Gtk::Widget*> seqList = box->get_children();
579 for (Glib::ListHandle<Gtk::Widget*>::iterator itt = seqList.begin();itt != seqList.end(); ++itt) {
580 sequence.push_back(dynamic_cast<Gtk::ToggleButton*>((*itt))->get_active());
581 }
582 seqc.setseqline(sequence);
583 p->set(seqc);
584 }
585
check_preset_label()586 void SEQWindow::check_preset_label() {
587 Glib::ustring pset = " ";
588 gx_preset::UnitPresetList presetnames;
589 machine.plugin_preset_list_load(machine.pluginlist_lookup_plugin("seq")->get_pdef(), presetnames);
590 gx_preset::UnitPresetList::iterator i = presetnames.begin();
591 for ( i = presetnames.begin(); i != presetnames.end(); ++i) {
592 if (!i->name.empty()) {
593 if (i->is_set) {
594 pset = i->name;
595 break;
596 }
597 }
598 }
599 preset_label->set_label(pset);
600 }
601
seq_changed(const gx_engine::GxSeqSettings * seqc,Gtk::Box * box)602 void SEQWindow::seq_changed(const gx_engine::GxSeqSettings* seqc, Gtk::Box *box) {
603
604 Glib::ListHandle<Gtk::Widget*> seqList = box->get_children();
605 Glib::ListHandle<Gtk::Widget*>::iterator itt = seqList.begin();
606 std::vector<int> sequence = seqc->getseqline();
607 int ic = int(machine.get_parameter_value<float>("seq.tact"))-1;
608 int i0 = ic;
609 for (std::vector<int>::const_iterator i = sequence.begin(); i != sequence.end(); ++i) {
610 if (itt == seqList.end()) break;
611 dynamic_cast<Gtk::ToggleButton*>((*itt))->set_active(*i);
612 if (i0 == ic) {
613 dynamic_cast<Gtk::ToggleButton*>((*itt))->set_name("seq_button");
614 i0 = 0;
615 } else {
616 dynamic_cast<Gtk::ToggleButton*>((*itt))->set_name("seqbutton");
617 ++i0;
618 }
619 ++itt;
620 }
621 Glib::signal_idle().connect_once(sigc::mem_fun(this, &SEQWindow::check_preset_label));
622 }
623
reload_and_show()624 void SEQWindow::reload_and_show() {
625 if (gtk_window->get_visible() && !(gtk_window->get_window()->get_state() & Gdk::WINDOW_STATE_ICONIFIED)) {
626 gtk_window->hide();
627 } else {
628 FOR_DRUMS(
629 seq_changed(&d.p->get_value(), d.box);
630 );
631 gtk_window->present();
632 std::string id;
633 seq_pos->get_property("var_id",id);
634
635 int ti_o = 60;
636 if (!machine.get_jack()) ti_o = 250;
637 Glib::signal_timeout().connect(
638 sigc::bind<Gxw::Regler*>(sigc::bind<const std::string>(
639 sigc::mem_fun(*this, &SEQWindow::get_sequencer_pos),id), seq_pos), ti_o);
640 }
641 }
642
~SEQWindow()643 SEQWindow::~SEQWindow() {
644 delete gtk_window;
645 }
646
647 } // end namespace
648