/[svn]/gigedit/trunk/src/mainwindow.cpp
ViewVC logotype

Contents of /gigedit/trunk/src/mainwindow.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1080 - (show annotations) (download)
Tue Mar 6 23:16:18 2007 UTC (16 years, 11 months ago) by schoenebeck
File size: 54384 byte(s)
* listview on the left is now tabbed into "Instruments" and new: "Samples",
  the latter are displayed in their respective sample group

1 /*
2 * Copyright (C) 2006, 2007 Andreas Persson
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with program; see the file COPYING. If not, write to the Free
16 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17 * 02110-1301 USA.
18 */
19
20 #include <libintl.h>
21 #include <iostream>
22
23 #include "mainwindow.h"
24
25 #include <gtkmm/filechooserdialog.h>
26 #include <gtkmm/stock.h>
27 #if GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 6
28 #define ABOUT_DIALOG
29 #include <gtkmm/aboutdialog.h>
30 #endif
31
32 #define _(String) gettext(String)
33
34 bool update_gui;
35
36 uint8_t& access_UnityNote(gig::DimensionRegion* dimreg)
37 {
38 return dimreg->UnityNote;
39 }
40 int16_t& access_FineTune(gig::DimensionRegion* dimreg)
41 {
42 return dimreg->FineTune;
43 }
44 uint32_t& access_SampleLoops(gig::DimensionRegion* dimreg)
45 {
46 return dimreg->SampleLoops;
47 }
48 uint8_t& access_Crossfade_in_start(gig::DimensionRegion* dimreg)
49 {
50 return dimreg->Crossfade.in_start;
51 }
52 uint8_t& access_Crossfade_in_end(gig::DimensionRegion* dimreg)
53 {
54 return dimreg->Crossfade.in_end;
55 }
56 uint8_t& access_Crossfade_out_start(gig::DimensionRegion* dimreg)
57 {
58 return dimreg->Crossfade.out_start;
59 }
60 uint8_t& access_Crossfade_out_end(gig::DimensionRegion* dimreg)
61 {
62 return dimreg->Crossfade.out_end;
63 }
64
65 namespace {
66 const char* const controlChangeTexts[] = {
67 "none", "channelaftertouch", "velocity",
68 0,
69 "modwheel", // "Modulation Wheel or Lever",
70 "breath", // "Breath Controller",
71 0,
72 "foot", // "Foot Controller",
73 "portamentotime", // "Portamento Time",
74 0, 0, 0, 0, 0, 0,
75 "effect1", // "Effect Control 1",
76 "effect2", // "Effect Control 2",
77 0, 0,
78 "genpurpose1", // "General Purpose Controller 1",
79 "genpurpose2", // "General Purpose Controller 2",
80 "genpurpose3", // "General Purpose Controller 3",
81 "genpurpose4", // "General Purpose Controller 4",
82 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0,
85 "sustainpedal", // "Damper Pedal on/off (Sustain)",
86 "portamento", // "Portamento On/Off",
87 "sostenuto", // "Sustenuto On/Off",
88 "softpedal", // "Soft Pedal On/Off",
89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90 "genpurpose5", // "General Purpose Controller 5",
91 "genpurpose6", // "General Purpose Controller 6",
92 "genpurpose7", // "General Purpose Controller 7",
93 "genpurpose8", // "General Purpose Controller 8",
94 0, 0, 0, 0, 0, 0, 0,
95 "effect1depth", // "Effects 1 Depth",
96 "effect2depth", // "Effects 2 Depth",
97 "effect3depth", // "Effects 3 Depth",
98 "effect4depth", // "Effects 4 Depth",
99 "effect5depth", // "Effects 5 Depth"
100 };
101 }
102
103 void MainWindow::addString(char* labelText, Gtk::Label*& label,
104 Gtk::Entry*& widget)
105 {
106 label = new Gtk::Label(Glib::ustring(labelText) + ":");
107 label->set_alignment(Gtk::ALIGN_LEFT);
108
109 table[pageno]->attach(*label, 1, 2, rowno, rowno + 1,
110 Gtk::FILL, Gtk::SHRINK);
111
112 widget = new Gtk::Entry();
113
114 table[pageno]->attach(*widget, 2, 3, rowno, rowno + 1,
115 Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
116
117 rowno++;
118 }
119
120 LabelWidget::LabelWidget(char* labelText, Gtk::Widget& widget) :
121 label(Glib::ustring(labelText) + ":"),
122 widget(widget)
123 {
124 label.set_alignment(Gtk::ALIGN_LEFT);
125 }
126
127 void LabelWidget::set_sensitive(bool sensitive)
128 {
129 label.set_sensitive(sensitive);
130 widget.set_sensitive(sensitive);
131 }
132
133 NumEntryGain::NumEntryGain(char* labelText,
134 double lower = 0, double upper = 127,
135 int decimals = 0) :
136 NumEntry<gig::DimensionRegion>(labelText, lower, upper, decimals)
137 {
138 spinbutton.signal_value_changed().connect(
139 sigc::mem_fun(*this, &NumEntryGain::value_changed));
140 }
141
142 void NumEntryGain::value_changed()
143 {
144 if (dimreg && update_gui) {
145 dimreg->Gain = int32_t(spinbutton.get_value() * -655360.0);
146 }
147 }
148
149 void NumEntryGain::set_dimreg(gig::DimensionRegion* dimreg)
150 {
151 this->dimreg = 0;
152 set_value(dimreg->Gain / -655360.0);
153 this->dimreg = dimreg;
154 }
155
156
157 NumEntryPermille::NumEntryPermille(char* labelText,
158 uint16_t gig::DimensionRegion::* param,
159 double lower, double upper, int decimals) :
160 NumEntry<gig::DimensionRegion>(labelText, lower, upper, decimals),
161 param(param)
162 {
163 spinbutton.signal_value_changed().connect(
164 sigc::mem_fun(*this, &NumEntryPermille::value_changed));
165 }
166
167 void NumEntryPermille::value_changed()
168 {
169 if (dimreg && update_gui) {
170 dimreg->*param = uint16_t(spinbutton.get_value() * 10 + 0.5);
171 }
172 }
173
174 void NumEntryPermille::set_dimreg(gig::DimensionRegion* dimreg)
175 {
176 this->dimreg = 0;
177 set_value(dimreg->*param / 10.0);
178 this->dimreg = dimreg;
179 }
180
181
182 NoteEntry::NoteEntry(char* labelText, uint8_t& (*access)(gig::DimensionRegion*)) :
183 NumEntryX<uint8_t>(labelText, access)
184 {
185 spinbutton.signal_input().connect(
186 sigc::mem_fun(*this, &NoteEntry::on_input));
187 spinbutton.signal_output().connect(
188 sigc::mem_fun(*this, &NoteEntry::on_output));
189 }
190
191 const char* notes[] = {
192 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
193 };
194
195
196 // Convert the Entry text to a number
197 int NoteEntry::on_input(double* new_value)
198 {
199 const char* str = spinbutton.get_text().c_str();
200
201 int i;
202 for (i = 11 ; i >= 0 ; i--) {
203 if (strncmp(str, notes[i], strlen(notes[i])) == 0) break;
204 }
205 if (i >= 0) {
206 char* endptr;
207 long x = strtol(str + strlen(notes[i]), &endptr, 10);
208 if (endptr != str + strlen(notes[i])) {
209 *new_value = i + (x + 1) * 12;
210 return true;
211 }
212 }
213 return Gtk::INPUT_ERROR;
214 }
215
216 // Convert the Adjustment position to text
217 bool NoteEntry::on_output()
218 {
219 int x = int(spinbutton.get_adjustment()->get_value());
220 char buf[10];
221 sprintf(buf, "%s%d", notes[x % 12], x / 12 - 1);
222 spinbutton.set_text(buf);
223 return true;
224 }
225
226 BoolEntry::BoolEntry(char* labelText, bool gig::DimensionRegion::* param) :
227 LabelWidget(labelText, checkbutton),
228 param(param)
229 {
230 checkbutton.signal_toggled().connect(
231 sigc::mem_fun(*this, &BoolEntry::value_changed));
232 }
233
234 void BoolEntry::value_changed()
235 {
236 if (dimreg && update_gui) {
237 dimreg->*param = checkbutton.get_active();
238 }
239 }
240
241 void BoolEntry::set_dimreg(gig::DimensionRegion* dimreg)
242 {
243 this->dimreg = 0;
244 checkbutton.set_active(dimreg->*param);
245 this->dimreg = dimreg;
246 }
247
248 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(
249 char* labelText,
250 gig::leverage_ctrl_t gig::DimensionRegion::* param) :
251 align(0, 0, 0, 0),
252 LabelWidget(labelText, align),
253 param(param)
254 {
255 for (int i = 0 ; i < 99 ; i++) {
256 if (controlChangeTexts[i]) {
257 combobox.append_text(controlChangeTexts[i]);
258 }
259 }
260 combobox.signal_changed().connect(
261 sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));
262 align.add(combobox);
263 }
264
265 void ChoiceEntryLeverageCtrl::value_changed()
266 {
267 if (dimreg && update_gui) {
268 int rowno = combobox.get_active_row_number();
269 switch (rowno)
270 {
271 case -1:
272 break;
273 case 0:
274 (dimreg->*param).type = gig::leverage_ctrl_t::type_none;
275 break;
276 case 1:
277 (dimreg->*param).type =
278 gig::leverage_ctrl_t::type_channelaftertouch;
279 break;
280 case 2:
281 (dimreg->*param).type = gig::leverage_ctrl_t::type_velocity;
282 break;
283 default:
284 (dimreg->*param).type = gig::leverage_ctrl_t::type_controlchange;
285 int x = 3;
286 for (int cc = 0 ; cc < 96 ; cc++) {
287 if (controlChangeTexts[cc + 3]) {
288 if (rowno == x) {
289 (dimreg->*param).controller_number = cc;
290 break;
291 }
292 x++;
293 }
294 }
295 break;
296 }
297 }
298 }
299
300 void ChoiceEntryLeverageCtrl::set_dimreg(gig::DimensionRegion* dimreg)
301 {
302 this->dimreg = 0;
303 gig::leverage_ctrl_t c = dimreg->*param;
304 int x;
305 switch (c.type)
306 {
307 case gig::leverage_ctrl_t::type_none:
308 x = 0;
309 break;
310 case gig::leverage_ctrl_t::type_channelaftertouch:
311 x = 1;
312 break;
313 case gig::leverage_ctrl_t::type_velocity:
314 x = 2;
315 break;
316 case gig::leverage_ctrl_t::type_controlchange:
317 x = -1;
318 for (int cc = 0 ; cc < 96 ; cc++) {
319 if (controlChangeTexts[cc + 3]) {
320 x++;
321 if (c.controller_number == cc) {
322 x += 3;
323 break;
324 }
325 }
326 }
327 break;
328 default:
329 x = -1;
330 break;
331 }
332 combobox.set_active(x);
333 this->dimreg = dimreg;
334 }
335
336 void MainWindow::addHeader(char* text)
337 {
338 if (firstRowInBlock < rowno - 1)
339 {
340 Gtk::Label* filler = new Gtk::Label(" ");
341 table[pageno]->attach(*filler, 0, 1, firstRowInBlock, rowno,
342 Gtk::FILL, Gtk::SHRINK);
343 }
344 Glib::ustring str = "<b>";
345 str += text;
346 str += "</b>";
347 Gtk::Label* label = new Gtk::Label(str);
348 label->set_use_markup();
349 label->set_alignment(Gtk::ALIGN_LEFT);
350 table[pageno]->attach(*label, 0, 3, rowno, rowno + 1,
351 Gtk::FILL, Gtk::SHRINK);
352 rowno++;
353 firstRowInBlock = rowno;
354 }
355
356 void MainWindow::nextPage()
357 {
358 if (firstRowInBlock < rowno - 1)
359 {
360 Gtk::Label* filler = new Gtk::Label(" ");
361 table[pageno]->attach(*filler, 0, 1, firstRowInBlock, rowno,
362 Gtk::FILL, Gtk::SHRINK);
363 }
364 pageno++;
365 rowno = 0;
366 firstRowInBlock = 0;
367 }
368
369 void MainWindow::addProp(LabelWidget& prop)
370 {
371 table[pageno]->attach(prop.label, 1, 2, rowno, rowno + 1,
372 Gtk::FILL, Gtk::SHRINK);
373 table[pageno]->attach(prop.widget, 2, 3, rowno, rowno + 1,
374 Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
375 rowno++;
376 }
377
378
379
380
381 MainWindow::MainWindow() :
382 // eSample("Sample", wSample),
383 eVelocityUpperLimit("VelocityUpperLimit",
384 &gig::DimensionRegion::VelocityUpperLimit),
385 eEG1PreAttack("PreAttack", &gig::DimensionRegion::EG1PreAttack, 0, 100, 2),
386 eEG1Attack("Attack", &gig::DimensionRegion::EG1Attack, 0, 60, 3),
387 eEG1Decay1("Decay1", &gig::DimensionRegion::EG1Decay1, 0.005, 60, 3),
388 eEG1Decay2("Decay2", &gig::DimensionRegion::EG1Decay2, 0, 60, 3),
389 eEG1InfiniteSustain("InfiniteSustain",
390 &gig::DimensionRegion::EG1InfiniteSustain),
391 eEG1Sustain("Sustain", &gig::DimensionRegion::EG1Sustain, 0, 100, 2),
392 eEG1Release("Release", &gig::DimensionRegion::EG1Release, 0, 60, 3),
393 eEG1Hold("Hold", &gig::DimensionRegion::EG1Hold),
394 eEG1Controller("Controller", &gig::DimensionRegion::EG1Controller),
395 eEG1ControllerInvert("ControllerInvert",
396 &gig::DimensionRegion::EG1ControllerInvert),
397 eEG1ControllerAttackInfluence("ControllerAttackInfluence",
398 &gig::DimensionRegion::EG1ControllerAttackInfluence,
399 0, 3),
400 eEG1ControllerDecayInfluence("ControllerDecayInfluence",
401 &gig::DimensionRegion::EG1ControllerDecayInfluence,
402 0, 3),
403 eEG1ControllerReleaseInfluence("ControllerReleaseInfluence",
404 &gig::DimensionRegion::EG1ControllerReleaseInfluence,
405 0, 3),
406 eLFO1Frequency("Frequency", &gig::DimensionRegion::LFO1Frequency,
407 0.1, 10, 2),
408 eLFO1InternalDepth("InternalDepth",
409 &gig::DimensionRegion::LFO1InternalDepth, 0, 1200),
410 eLFO1ControlDepth("ControlDepth", &gig::DimensionRegion::LFO1ControlDepth,
411 0, 1200),
412 eLFO1Controller("Controller", &gig::DimensionRegion::LFO1Controller),
413 eLFO1FlipPhase("FlipPhase", &gig::DimensionRegion::LFO1FlipPhase),
414 eLFO1Sync("Sync", &gig::DimensionRegion::LFO1Sync),
415 eEG2PreAttack("PreAttack", &gig::DimensionRegion::EG2PreAttack, 0, 100, 2),
416 eEG2Attack("Attack", &gig::DimensionRegion::EG2Attack, 0, 60, 3),
417 eEG2Decay1("Decay1", &gig::DimensionRegion::EG2Decay1, 0.005, 60, 3),
418 eEG2Decay2("Decay2", &gig::DimensionRegion::EG2Decay2, 0, 60, 3),
419 eEG2InfiniteSustain("InfiniteSustain",
420 &gig::DimensionRegion::EG2InfiniteSustain),
421 eEG2Sustain("Sustain", &gig::DimensionRegion::EG2Sustain, 0, 100, 2),
422 eEG2Release("Release", &gig::DimensionRegion::EG2Release, 0, 60, 3),
423 eEG2Controller("Controller", &gig::DimensionRegion::EG2Controller),
424 eEG2ControllerInvert("ControllerInvert",
425 &gig::DimensionRegion::EG2ControllerInvert),
426 eEG2ControllerAttackInfluence("ControllerAttackInfluence",
427 &gig::DimensionRegion::EG2ControllerAttackInfluence,
428 0, 3),
429 eEG2ControllerDecayInfluence("ControllerDecayInfluence",
430 &gig::DimensionRegion::EG2ControllerDecayInfluence,
431 0, 3),
432 eEG2ControllerReleaseInfluence("ControllerReleaseInfluence",
433 &gig::DimensionRegion::EG2ControllerReleaseInfluence,
434 0, 3),
435 eLFO2Frequency("Frequency", &gig::DimensionRegion::LFO2Frequency,
436 0.1, 10, 2),
437 eLFO2InternalDepth("InternalDepth",
438 &gig::DimensionRegion::LFO2InternalDepth, 0, 1200),
439 eLFO2ControlDepth("ControlDepth",
440 &gig::DimensionRegion::LFO2ControlDepth, 0, 1200),
441 eLFO2Controller("Controller", &gig::DimensionRegion::LFO2Controller),
442 eLFO2FlipPhase("FlipPhase", &gig::DimensionRegion::LFO2FlipPhase),
443 eLFO2Sync("Sync", &gig::DimensionRegion::LFO2Sync),
444 eEG3Attack("Attack", &gig::DimensionRegion::EG3Attack, 0, 10, 3),
445 eEG3Depth("Depth", &gig::DimensionRegion::EG3Depth, -1200, 1200),
446 eLFO3Frequency("Frequency", &gig::DimensionRegion::LFO3Frequency,
447 0.1, 10, 2),
448 eLFO3InternalDepth("InternalDepth",
449 &gig::DimensionRegion::LFO3InternalDepth, 0, 1200),
450 eLFO3ControlDepth("ControlDepth", &gig::DimensionRegion::LFO3ControlDepth,
451 0, 1200),
452 eLFO3Controller("Controller", &gig::DimensionRegion::LFO3Controller),
453 eLFO3Sync("Sync", &gig::DimensionRegion::LFO3Sync),
454 eVCFEnabled("Enabled", &gig::DimensionRegion::VCFEnabled),
455 eVCFType("Type", &gig::DimensionRegion::VCFType),
456 eVCFCutoffController("CutoffController",
457 &gig::DimensionRegion::VCFCutoffController),
458 eVCFCutoffControllerInvert("CutoffControllerInvert",
459 &gig::DimensionRegion::VCFCutoffControllerInvert),
460 eVCFCutoff("Cutoff", &gig::DimensionRegion::VCFCutoff),
461 eVCFVelocityCurve("VelocityCurve", &gig::DimensionRegion::VCFVelocityCurve),
462 eVCFVelocityScale("VelocityScale", &gig::DimensionRegion::VCFVelocityScale),
463 eVCFVelocityDynamicRange("VelocityDynamicRange",
464 &gig::DimensionRegion::VCFVelocityDynamicRange,
465 0, 4),
466 eVCFResonance("Resonance", &gig::DimensionRegion::VCFResonance),
467 eVCFResonanceDynamic("ResonanceDynamic",
468 &gig::DimensionRegion::VCFResonanceDynamic),
469 eVCFResonanceController("ResonanceController",
470 &gig::DimensionRegion::VCFResonanceController),
471 eVCFKeyboardTracking("KeyboardTracking",
472 &gig::DimensionRegion::VCFKeyboardTracking),
473 eVCFKeyboardTrackingBreakpoint("KeyboardTrackingBreakpoint",
474 &gig::DimensionRegion::VCFKeyboardTrackingBreakpoint),
475 eVelocityResponseCurve("VelocityResponseCurve",
476 &gig::DimensionRegion::VelocityResponseCurve),
477 eVelocityResponseDepth("VelocityResponseDepth",
478 &gig::DimensionRegion::VelocityResponseDepth, 0, 4),
479 eVelocityResponseCurveScaling("VelocityResponseCurveScaling",
480 &gig::DimensionRegion::VelocityResponseCurveScaling),
481 eReleaseVelocityResponseCurve("ReleaseVelocityResponseCurve",
482 &gig::DimensionRegion::ReleaseVelocityResponseCurve),
483 eReleaseVelocityResponseDepth("ReleaseVelocityResponseDepth",
484 &gig::DimensionRegion::ReleaseVelocityResponseDepth,
485 0, 4),
486 eReleaseTriggerDecay("ReleaseTriggerDecay",
487 &gig::DimensionRegion::ReleaseTriggerDecay, 0, 8),
488 eCrossfade_in_start("Crossfade.in_start", &access_Crossfade_in_start),
489 eCrossfade_in_end("Crossfade.in_end", &access_Crossfade_in_end),
490 eCrossfade_out_start("Crossfade.out_start", &access_Crossfade_out_start),
491 eCrossfade_out_end("Crossfade.out_end", &access_Crossfade_out_end),
492 ePitchTrack("PitchTrack", &gig::DimensionRegion::PitchTrack),
493 eDimensionBypass("DimensionBypass", &gig::DimensionRegion::DimensionBypass),
494 ePan("Pan", &gig::DimensionRegion::Pan, -64, 63),
495 eSelfMask("SelfMask", &gig::DimensionRegion::SelfMask),
496 eAttenuationController("AttenuationController",
497 &gig::DimensionRegion::AttenuationController),
498 eInvertAttenuationController("InvertAttenuationController",
499 &gig::DimensionRegion::InvertAttenuationController),
500 eAttenuationControllerThreshold("AttenuationControllerThreshold",
501 &gig::DimensionRegion::AttenuationControllerThreshold),
502 eChannelOffset("ChannelOffset", &gig::DimensionRegion::ChannelOffset, 0, 9),
503 eSustainDefeat("SustainDefeat", &gig::DimensionRegion::SustainDefeat),
504 eMSDecode("MSDecode", &gig::DimensionRegion::MSDecode),
505 eSampleStartOffset("SampleStartOffset",
506 &gig::DimensionRegion::SampleStartOffset, 0, 2000),
507 eUnityNote("UnityNote", &access_UnityNote),
508 eFineTune("FineTune", &access_FineTune, -49, 50),
509 eGain("Gain", -96, 0, 2),
510 eSampleLoops("SampleLoops", &access_SampleLoops, 0, 1)
511 {
512 // set_border_width(5);
513 set_default_size(400, 200);
514
515
516 add(m_VBox);
517
518 // Handle selection
519 Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
520 tree_sel_ref->signal_changed().connect(
521 sigc::mem_fun(*this, &MainWindow::on_sel_change));
522
523 m_TreeView.signal_button_press_event().connect_notify(
524 sigc::mem_fun(*this, &MainWindow::on_button_release));
525
526 // Add the TreeView tab, inside a ScrolledWindow, with the button underneath:
527 m_ScrolledWindow.add(m_TreeViewNotebook);
528 m_ScrolledWindow.set_size_request(400, 600);
529 m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
530
531 for (int i = 0 ; i < 5 ; i++) {
532 table[i] = new Gtk::Table(3, 1);
533 table[i]->set_col_spacings(5);
534 }
535
536 pageno = 0;
537 rowno = 0;
538 firstRowInBlock = 0;
539
540 addString("Sample", lSample, wSample);
541 addProp(eVelocityUpperLimit);
542 addHeader("EG1");
543 addProp(eEG1PreAttack);
544 addProp(eEG1Attack);
545 addProp(eEG1Decay1);
546 addProp(eEG1Decay2);
547 addProp(eEG1InfiniteSustain);
548 addProp(eEG1Sustain);
549 addProp(eEG1Release);
550 addProp(eEG1Hold);
551 addProp(eEG1Controller);
552 addProp(eEG1ControllerInvert);
553 addProp(eEG1ControllerAttackInfluence);
554 addProp(eEG1ControllerDecayInfluence);
555 addProp(eEG1ControllerReleaseInfluence);
556 addHeader("LFO1");
557 addProp(eLFO1Frequency);
558 addProp(eLFO1InternalDepth);
559 addProp(eLFO1ControlDepth);
560 {
561 char* choices[] = { "internal", "modwheel", "breath",
562 "internal+modwheel", "internal+breath", 0 };
563 static const gig::lfo1_ctrl_t values[] = {
564 gig::lfo1_ctrl_internal,
565 gig::lfo1_ctrl_modwheel,
566 gig::lfo1_ctrl_breath,
567 gig::lfo1_ctrl_internal_modwheel,
568 gig::lfo1_ctrl_internal_breath
569 };
570 eLFO1Controller.set_choices(choices, values);
571 }
572 addProp(eLFO1Controller);
573 addProp(eLFO1FlipPhase);
574 addProp(eLFO1Sync);
575
576 nextPage();
577 addHeader("EG2");
578 addProp(eEG2PreAttack);
579 addProp(eEG2Attack);
580 addProp(eEG2Decay1);
581 addProp(eEG2Decay2);
582 addProp(eEG2InfiniteSustain);
583 addProp(eEG2Sustain);
584 addProp(eEG2Release);
585 addProp(eEG2Controller);
586 addProp(eEG2ControllerInvert);
587 addProp(eEG2ControllerAttackInfluence);
588 addProp(eEG2ControllerDecayInfluence);
589 addProp(eEG2ControllerReleaseInfluence);
590 addHeader("LFO2");
591 addProp(eLFO2Frequency);
592 addProp(eLFO2InternalDepth);
593 addProp(eLFO2ControlDepth);
594 {
595 char* choices[] = { "internal", "modwheel", "foot",
596 "internal+modwheel", "internal+foot", 0 };
597 static const gig::lfo2_ctrl_t values[] = {
598 gig::lfo2_ctrl_internal,
599 gig::lfo2_ctrl_modwheel,
600 gig::lfo2_ctrl_foot,
601 gig::lfo2_ctrl_internal_modwheel,
602 gig::lfo2_ctrl_internal_foot
603 };
604 eLFO2Controller.set_choices(choices, values);
605 }
606 addProp(eLFO2Controller);
607 addProp(eLFO2FlipPhase);
608 addProp(eLFO2Sync);
609
610 nextPage();
611
612 addHeader("EG3");
613 addProp(eEG3Attack);
614 addProp(eEG3Depth);
615 addHeader("LFO3");
616 addProp(eLFO3Frequency);
617 addProp(eLFO3InternalDepth);
618 addProp(eLFO3ControlDepth);
619 {
620 char* choices[] = { "internal", "modwheel", "aftertouch",
621 "internal+modwheel", "internal+aftertouch", 0 };
622 static const gig::lfo3_ctrl_t values[] = {
623 gig::lfo3_ctrl_internal,
624 gig::lfo3_ctrl_modwheel,
625 gig::lfo3_ctrl_aftertouch,
626 gig::lfo3_ctrl_internal_modwheel,
627 gig::lfo3_ctrl_internal_aftertouch
628 };
629 eLFO3Controller.set_choices(choices, values);
630 }
631 addProp(eLFO3Controller);
632 addProp(eLFO3Sync);
633 addHeader("VCF");
634 addProp(eVCFEnabled);
635 {
636 char* choices[] = { "lowpass", "lowpassturbo", "bandpass",
637 "highpass", "bandreject", 0 };
638 static const gig::vcf_type_t values[] = {
639 gig::vcf_type_lowpass,
640 gig::vcf_type_lowpassturbo,
641 gig::vcf_type_bandpass,
642 gig::vcf_type_highpass,
643 gig::vcf_type_bandreject
644 };
645 eVCFType.set_choices(choices, values);
646 }
647 addProp(eVCFType);
648 {
649 char* choices[] = { "none", "none2", "modwheel", "effect1", "effect2",
650 "breath", "foot", "sustainpedal", "softpedal",
651 "genpurpose7", "genpurpose8", "aftertouch", 0 };
652 static const gig::vcf_cutoff_ctrl_t values[] = {
653 gig::vcf_cutoff_ctrl_none,
654 gig::vcf_cutoff_ctrl_none2,
655 gig::vcf_cutoff_ctrl_modwheel,
656 gig::vcf_cutoff_ctrl_effect1,
657 gig::vcf_cutoff_ctrl_effect2,
658 gig::vcf_cutoff_ctrl_breath,
659 gig::vcf_cutoff_ctrl_foot,
660 gig::vcf_cutoff_ctrl_sustainpedal,
661 gig::vcf_cutoff_ctrl_softpedal,
662 gig::vcf_cutoff_ctrl_genpurpose7,
663 gig::vcf_cutoff_ctrl_genpurpose8,
664 gig::vcf_cutoff_ctrl_aftertouch
665 };
666 eVCFCutoffController.set_choices(choices, values);
667 }
668 addProp(eVCFCutoffController);
669 addProp(eVCFCutoffControllerInvert);
670 addProp(eVCFCutoff);
671 char* curve_type_texts[] = { "nonlinear", "linear", "special", 0 };
672 static const gig::curve_type_t curve_type_values[] = {
673 gig::curve_type_nonlinear,
674 gig::curve_type_linear,
675 gig::curve_type_special
676 };
677 eVCFVelocityCurve.set_choices(curve_type_texts, curve_type_values);
678 addProp(eVCFVelocityCurve);
679 addProp(eVCFVelocityScale);
680 addProp(eVCFVelocityDynamicRange);
681 addProp(eVCFResonance);
682 addProp(eVCFResonanceDynamic);
683 {
684 char* choices[] = { "none", "genpurpose3", "genpurpose4",
685 "genpurpose5", "genpurpose6", 0 };
686 static const gig::vcf_res_ctrl_t values[] = {
687 gig::vcf_res_ctrl_none,
688 gig::vcf_res_ctrl_genpurpose3,
689 gig::vcf_res_ctrl_genpurpose4,
690 gig::vcf_res_ctrl_genpurpose5,
691 gig::vcf_res_ctrl_genpurpose6
692 };
693 eVCFResonanceController.set_choices(choices, values);
694 }
695 addProp(eVCFResonanceController);
696 addProp(eVCFKeyboardTracking);
697 addProp(eVCFKeyboardTrackingBreakpoint);
698
699 nextPage();
700
701 eVelocityResponseCurve.set_choices(curve_type_texts, curve_type_values);
702 addProp(eVelocityResponseCurve);
703 addProp(eVelocityResponseDepth);
704 addProp(eVelocityResponseCurveScaling);
705 eReleaseVelocityResponseCurve.set_choices(curve_type_texts,
706 curve_type_values);
707 addProp(eReleaseVelocityResponseCurve);
708 addProp(eReleaseVelocityResponseDepth);
709 addProp(eReleaseTriggerDecay);
710 addProp(eCrossfade_in_start);
711 addProp(eCrossfade_in_end);
712 addProp(eCrossfade_out_start);
713 addProp(eCrossfade_out_end);
714 addProp(ePitchTrack);
715 {
716 char* choices[] = { "none", "effect4depth", "effect5depth", 0 };
717 static const gig::dim_bypass_ctrl_t values[] = {
718 gig::dim_bypass_ctrl_none,
719 gig::dim_bypass_ctrl_94,
720 gig::dim_bypass_ctrl_95
721 };
722 eDimensionBypass.set_choices(choices, values);
723 }
724 addProp(eDimensionBypass);
725 addProp(ePan);
726 addProp(eSelfMask);
727 addProp(eAttenuationController);
728 addProp(eInvertAttenuationController);
729 addProp(eAttenuationControllerThreshold);
730 addProp(eChannelOffset);
731 addProp(eSustainDefeat);
732
733 nextPage();
734 addProp(eMSDecode);
735 addProp(eSampleStartOffset);
736 addProp(eUnityNote);
737 addProp(eFineTune);
738 addProp(eGain);
739 addProp(eSampleLoops);
740 nextPage();
741
742 eEG1InfiniteSustain.signal_toggled().connect(
743 sigc::mem_fun(*this, &MainWindow::EG1InfiniteSustain_toggled) );
744 eEG2InfiniteSustain.signal_toggled().connect(
745 sigc::mem_fun(*this, &MainWindow::EG2InfiniteSustain_toggled) );
746 eEG1Controller.signal_changed().connect(
747 sigc::mem_fun(*this, &MainWindow::EG1Controller_changed) );
748 eEG2Controller.signal_changed().connect(
749 sigc::mem_fun(*this, &MainWindow::EG2Controller_changed) );
750 eLFO1Controller.signal_changed().connect(
751 sigc::mem_fun(*this, &MainWindow::LFO1Controller_changed) );
752 eLFO2Controller.signal_changed().connect(
753 sigc::mem_fun(*this, &MainWindow::LFO2Controller_changed) );
754 eLFO3Controller.signal_changed().connect(
755 sigc::mem_fun(*this, &MainWindow::LFO3Controller_changed) );
756 eAttenuationController.signal_changed().connect(
757 sigc::mem_fun(*this, &MainWindow::AttenuationController_changed) );
758 eVCFEnabled.signal_toggled().connect(
759 sigc::mem_fun(*this, &MainWindow::VCFEnabled_toggled) );
760 eVCFCutoffController.signal_changed().connect(
761 sigc::mem_fun(*this, &MainWindow::VCFCutoffController_changed) );
762 eVCFResonanceController.signal_changed().connect(
763 sigc::mem_fun(*this, &MainWindow::VCFResonanceController_changed) );
764
765 eCrossfade_in_start.signal_value_changed().connect(
766 sigc::mem_fun(*this, &MainWindow::crossfade1_changed));
767 eCrossfade_in_end.signal_value_changed().connect(
768 sigc::mem_fun(*this, &MainWindow::crossfade2_changed));
769 eCrossfade_out_start.signal_value_changed().connect(
770 sigc::mem_fun(*this, &MainWindow::crossfade3_changed));
771 eCrossfade_out_end.signal_value_changed().connect(
772 sigc::mem_fun(*this, &MainWindow::crossfade4_changed));
773
774 //m_Notebook.append_page(m_ScrolledWindow2, "Table");
775 m_Notebook.append_page(*table[0], "EG1");
776 m_Notebook.append_page(*table[1], "EG2");
777 m_Notebook.append_page(*table[2], "EG3");
778 m_Notebook.append_page(*table[3], "Velocity");
779 m_Notebook.append_page(*table[4], "Misc");
780 m_Notebook.set_size_request(400, 500);
781
782 m_HPaned.add1(m_ScrolledWindow);
783 m_HPaned.add2(m_Notebook);
784
785
786 m_TreeViewNotebook.append_page(m_TreeViewSamples, "Samples");
787 m_TreeViewNotebook.append_page(m_TreeView, "Instruments");
788
789
790 actionGroup = Gtk::ActionGroup::create();
791
792 actionGroup->add(Gtk::Action::create("MenuFile", _("_File")));
793 actionGroup->add(Gtk::Action::create("New", Gtk::Stock::NEW),
794 sigc::mem_fun(
795 *this, &MainWindow::on_action_file_new));
796 Glib::RefPtr<Gtk::Action> action =
797 Gtk::Action::create("Open", Gtk::Stock::OPEN);
798 action->property_label() = action->property_label() + "...";
799 actionGroup->add(action,
800 sigc::mem_fun(
801 *this, &MainWindow::on_action_file_open));
802 actionGroup->add(Gtk::Action::create("Save", Gtk::Stock::SAVE),
803 sigc::mem_fun(
804 *this, &MainWindow::on_action_file_save));
805 action = Gtk::Action::create("SaveAs", Gtk::Stock::SAVE_AS);
806 action->property_label() = action->property_label() + "...";
807 actionGroup->add(action,
808 *(new Gtk::AccelKey("<shift><control>s")),
809 sigc::mem_fun(
810 *this, &MainWindow::on_action_file_save_as)
811 );
812 actionGroup->add(Gtk::Action::create("Properties",
813 Gtk::Stock::PROPERTIES),
814 sigc::mem_fun(
815 *this, &MainWindow::on_action_file_properties));
816 actionGroup->add(Gtk::Action::create("InstrProperties",
817 Gtk::Stock::PROPERTIES),
818 sigc::mem_fun(
819 *this, &MainWindow::on_action_file_properties));
820 actionGroup->add(Gtk::Action::create("Quit", Gtk::Stock::QUIT),
821 sigc::mem_fun(
822 *this, &MainWindow::hide));
823 actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));
824
825 action = Gtk::Action::create("MenuHelp", Gtk::Stock::HELP);
826 actionGroup->add(Gtk::Action::create("MenuHelp",
827 action->property_label()));
828 #ifdef ABOUT_DIALOG
829 actionGroup->add(Gtk::Action::create("About", Gtk::Stock::ABOUT),
830 sigc::mem_fun(
831 *this, &MainWindow::on_action_help_about));
832 #endif
833 action = Gtk::Action::create("Remove", "Ta bort");
834 actionGroup->add(action,
835 sigc::mem_fun(
836 *this, &MainWindow::hide));
837
838 uiManager = Gtk::UIManager::create();
839 uiManager->insert_action_group(actionGroup);
840 // add_accel_group(uiManager->get_accel_group());
841
842 Glib::ustring ui_info =
843 "<ui>"
844 " <menubar name='MenuBar'>"
845 " <menu action='MenuFile'>"
846 " <menuitem action='New'/>"
847 " <menuitem action='Open'/>"
848 " <separator/>"
849 " <menuitem action='Save'/>"
850 " <menuitem action='SaveAs'/>"
851 " <separator/>"
852 " <menuitem action='Properties'/>"
853 " <separator/>"
854 " <menuitem action='Quit'/>"
855 " </menu>"
856 " <menu action='MenuInstrument'>"
857 " </menu>"
858 #ifdef ABOUT_DIALOG
859 " <menu action='MenuHelp'>"
860 " <menuitem action='About'/>"
861 " </menu>"
862 #endif
863 " </menubar>"
864 " <popup name='PopupMenu'>"
865 " <menuitem action='InstrProperties'/>"
866 " <menuitem action='Remove'/>"
867 " </popup>"
868 "</ui>";
869 uiManager->add_ui_from_string(ui_info);
870
871 popup_menu = dynamic_cast<Gtk::Menu*>(uiManager->get_widget("/PopupMenu"));
872
873 Gtk::Widget* menuBar = uiManager->get_widget("/MenuBar");
874 m_VBox.pack_start(*menuBar, Gtk::PACK_SHRINK);
875 m_VBox.pack_start(m_HPaned);
876 m_VBox.pack_start(m_RegionChooser, Gtk::PACK_SHRINK);
877 m_VBox.pack_start(m_DimRegionChooser, Gtk::PACK_SHRINK);
878
879 m_RegionChooser.signal_sel_changed().connect(
880 sigc::mem_fun(*this, &MainWindow::region_changed) );
881 m_DimRegionChooser.signal_sel_changed().connect(
882 sigc::mem_fun(*this, &MainWindow::dimreg_changed) );
883
884
885 // Create the Tree model:
886 m_refTreeModel = Gtk::ListStore::create(m_Columns);
887 m_TreeView.set_model(m_refTreeModel);
888
889 // Add the TreeView's view columns:
890 m_TreeView.append_column("Instrument", m_Columns.m_col_name);
891 m_TreeView.set_headers_visible(false);
892
893 // create samples treeview (including its data model)
894 m_refSamplesTreeModel = Gtk::TreeStore::create(m_SamplesModel);
895 m_TreeViewSamples.set_model(m_refSamplesTreeModel);
896 m_TreeViewSamples.append_column("Samples", m_SamplesModel.m_col_name);
897 m_TreeViewSamples.set_headers_visible(false);
898
899 file = 0;
900
901 show_all_children();
902 }
903
904 MainWindow::~MainWindow()
905 {
906 }
907
908 void MainWindow::region_changed()
909 {
910 m_DimRegionChooser.set_region(m_RegionChooser.get_region());
911 }
912
913 void MainWindow::dimreg_changed()
914 {
915 set_dim_region(m_DimRegionChooser.get_dimregion());
916 }
917
918 void MainWindow::on_sel_change()
919 {
920 Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
921
922 Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();
923 if (it)
924 {
925 Gtk::TreeModel::Row row = *it;
926 std::cout << row[m_Columns.m_col_name] << std::endl;
927
928 if (row[m_Columns.m_col_instr])
929 m_RegionChooser.set_instrument(row[m_Columns.m_col_instr]);
930 }
931 }
932
933 void MainWindow::set_dim_region(gig::DimensionRegion* d)
934 {
935 update_gui = false;
936 wSample->set_text(d->pSample ? d->pSample->pInfo->Name.c_str() : "NULL");
937 eVelocityUpperLimit.set_dimreg(d);
938 eEG1PreAttack.set_dimreg(d);
939 eEG1Attack.set_dimreg(d);
940 eEG1Decay1.set_dimreg(d);
941 eEG1Decay2.set_dimreg(d);
942 eEG1InfiniteSustain.set_dimreg(d);
943 eEG1Sustain.set_dimreg(d);
944 eEG1Release.set_dimreg(d);
945 eEG1Hold.set_dimreg(d);
946 eEG1Controller.set_dimreg(d);
947 eEG1ControllerInvert.set_dimreg(d);
948 eEG1ControllerAttackInfluence.set_dimreg(d);
949 eEG1ControllerDecayInfluence.set_dimreg(d);
950 eEG1ControllerReleaseInfluence.set_dimreg(d);
951 eLFO1Frequency.set_dimreg(d);
952 eLFO1InternalDepth.set_dimreg(d);
953 eLFO1ControlDepth.set_dimreg(d);
954 eLFO1Controller.set_dimreg(d);
955 eLFO1FlipPhase.set_dimreg(d);
956 eLFO1Sync.set_dimreg(d);
957 eEG2PreAttack.set_dimreg(d);
958 eEG2Attack.set_dimreg(d);
959 eEG2Decay1.set_dimreg(d);
960 eEG2Decay2.set_dimreg(d);
961 eEG2InfiniteSustain.set_dimreg(d);
962 eEG2Sustain.set_dimreg(d);
963 eEG2Release.set_dimreg(d);
964 eEG2Controller.set_dimreg(d);
965 eEG2ControllerInvert.set_dimreg(d);
966 eEG2ControllerAttackInfluence.set_dimreg(d);
967 eEG2ControllerDecayInfluence.set_dimreg(d);
968 eEG2ControllerReleaseInfluence.set_dimreg(d);
969 eLFO2Frequency.set_dimreg(d);
970 eLFO2InternalDepth.set_dimreg(d);
971 eLFO2ControlDepth.set_dimreg(d);
972 eLFO2Controller.set_dimreg(d);
973 eLFO2FlipPhase.set_dimreg(d);
974 eLFO2Sync.set_dimreg(d);
975 eEG3Attack.set_dimreg(d);
976 eEG3Depth.set_dimreg(d);
977 eLFO3Frequency.set_dimreg(d);
978 eLFO3InternalDepth.set_dimreg(d);
979 eLFO3ControlDepth.set_dimreg(d);
980 eLFO3Controller.set_dimreg(d);
981 eLFO3Sync.set_dimreg(d);
982 eVCFEnabled.set_dimreg(d);
983 eVCFType.set_dimreg(d);
984 eVCFCutoffController.set_dimreg(d);
985 eVCFCutoffControllerInvert.set_dimreg(d);
986 eVCFCutoff.set_dimreg(d);
987 eVCFVelocityCurve.set_dimreg(d);
988 eVCFVelocityScale.set_dimreg(d);
989 eVCFVelocityDynamicRange.set_dimreg(d);
990 eVCFResonance.set_dimreg(d);
991 eVCFResonanceDynamic.set_dimreg(d);
992 eVCFResonanceController.set_dimreg(d);
993 eVCFKeyboardTracking.set_dimreg(d);
994 eVCFKeyboardTrackingBreakpoint.set_dimreg(d);
995 eVelocityResponseCurve.set_dimreg(d);
996 eVelocityResponseDepth.set_dimreg(d);
997 eVelocityResponseCurveScaling.set_dimreg(d);
998 eReleaseVelocityResponseCurve.set_dimreg(d);
999 eReleaseVelocityResponseDepth.set_dimreg(d);
1000 eReleaseTriggerDecay.set_dimreg(d);
1001 eCrossfade_in_start.set_dimreg(d);
1002 eCrossfade_in_end.set_dimreg(d);
1003 eCrossfade_out_start.set_dimreg(d);
1004 eCrossfade_out_end.set_dimreg(d);
1005 ePitchTrack.set_dimreg(d);
1006 eDimensionBypass.set_dimreg(d);
1007 ePan.set_dimreg(d);
1008 eSelfMask.set_dimreg(d);
1009 eAttenuationController.set_dimreg(d);
1010 eInvertAttenuationController.set_dimreg(d);
1011 eAttenuationControllerThreshold.set_dimreg(d);
1012 eChannelOffset.set_dimreg(d);
1013 eSustainDefeat.set_dimreg(d);
1014 eMSDecode.set_dimreg(d);
1015 eSampleStartOffset.set_dimreg(d);
1016 eUnityNote.set_dimreg(d);
1017 eFineTune.set_dimreg(d);
1018 eGain.set_dimreg(d);
1019 eSampleLoops.set_dimreg(d);
1020
1021 VCFEnabled_toggled();
1022
1023 update_gui = true;
1024 }
1025
1026 void MainWindow::VCFEnabled_toggled()
1027 {
1028 bool sensitive = eVCFEnabled.get_active();
1029 eVCFType.set_sensitive(sensitive);
1030 eVCFCutoffController.set_sensitive(sensitive);
1031 eVCFVelocityCurve.set_sensitive(sensitive);
1032 eVCFVelocityScale.set_sensitive(sensitive);
1033 eVCFVelocityDynamicRange.set_sensitive(sensitive);
1034 eVCFResonance.set_sensitive(sensitive);
1035 eVCFResonanceController.set_sensitive(sensitive);
1036 eVCFKeyboardTracking.set_sensitive(sensitive);
1037 eVCFKeyboardTrackingBreakpoint.set_sensitive(sensitive);
1038 eEG2PreAttack.set_sensitive(sensitive);
1039 eEG2Attack.set_sensitive(sensitive);
1040 eEG2Decay1.set_sensitive(sensitive);
1041 eEG2InfiniteSustain.set_sensitive(sensitive);
1042 eEG2Sustain.set_sensitive(sensitive);
1043 eEG2Release.set_sensitive(sensitive);
1044 eEG2Controller.set_sensitive(sensitive);
1045 eEG2ControllerAttackInfluence.set_sensitive(sensitive);
1046 eEG2ControllerDecayInfluence.set_sensitive(sensitive);
1047 eEG2ControllerReleaseInfluence.set_sensitive(sensitive);
1048 eLFO2Frequency.set_sensitive(sensitive);
1049 eLFO2InternalDepth.set_sensitive(sensitive);
1050 eLFO2ControlDepth.set_sensitive(sensitive);
1051 eLFO2Controller.set_sensitive(sensitive);
1052 eLFO2FlipPhase.set_sensitive(sensitive);
1053 eLFO2Sync.set_sensitive(sensitive);
1054 if (sensitive) {
1055 VCFCutoffController_changed();
1056 VCFResonanceController_changed();
1057 EG2InfiniteSustain_toggled();
1058 EG2Controller_changed();
1059 LFO2Controller_changed();
1060 } else {
1061 eVCFCutoffControllerInvert.set_sensitive(false);
1062 eVCFCutoff.set_sensitive(false);
1063 eVCFResonanceDynamic.set_sensitive(false);
1064 eVCFResonance.set_sensitive(false);
1065 eEG2Decay2.set_sensitive(false);
1066 eEG2ControllerInvert.set_sensitive(false);
1067 eLFO2InternalDepth.set_sensitive(false);
1068 eLFO2ControlDepth.set_sensitive(false);
1069 }
1070 }
1071
1072 void MainWindow::VCFCutoffController_changed()
1073 {
1074 int rowno = eVCFCutoffController.get_active_row_number();
1075 bool hasController = rowno != 0 && rowno != 1;
1076
1077 eVCFCutoffControllerInvert.set_sensitive(hasController);
1078 eVCFCutoff.set_sensitive(!hasController);
1079 eVCFResonanceDynamic.set_sensitive(!hasController);
1080 eVCFVelocityScale.label.set_text(hasController ? "MinimumCutoff:" :
1081 "VelocityScale:");
1082 }
1083
1084 void MainWindow::VCFResonanceController_changed()
1085 {
1086 bool hasController = eVCFResonanceController.get_active_row_number() != 0;
1087 eVCFResonance.set_sensitive(!hasController);
1088 }
1089
1090 void MainWindow::EG1InfiniteSustain_toggled()
1091 {
1092 bool infSus = eEG1InfiniteSustain.get_active();
1093 eEG1Decay2.set_sensitive(!infSus);
1094 }
1095
1096 void MainWindow::EG2InfiniteSustain_toggled()
1097 {
1098 bool infSus = eEG2InfiniteSustain.get_active();
1099 eEG2Decay2.set_sensitive(!infSus);
1100 }
1101
1102 void MainWindow::EG1Controller_changed()
1103 {
1104 bool hasController = eEG1Controller.get_active_row_number() != 0;
1105 eEG1ControllerInvert.set_sensitive(hasController);
1106 }
1107
1108 void MainWindow::EG2Controller_changed()
1109 {
1110 bool hasController = eEG2Controller.get_active_row_number() != 0;
1111 eEG2ControllerInvert.set_sensitive(hasController);
1112 }
1113
1114 void MainWindow::AttenuationController_changed()
1115 {
1116 bool hasController = eAttenuationController.get_active_row_number() != 0;
1117 eInvertAttenuationController.set_sensitive(hasController);
1118 }
1119
1120 void MainWindow::LFO1Controller_changed()
1121 {
1122 int rowno = eLFO1Controller.get_active_row_number();
1123 eLFO1ControlDepth.set_sensitive(rowno != 0);
1124 eLFO1InternalDepth.set_sensitive(rowno != 1 && rowno != 2);
1125 }
1126
1127 void MainWindow::LFO2Controller_changed()
1128 {
1129 int rowno = eLFO2Controller.get_active_row_number();
1130 eLFO2ControlDepth.set_sensitive(rowno != 0);
1131 eLFO2InternalDepth.set_sensitive(rowno != 1 && rowno != 2);
1132 }
1133
1134 void MainWindow::LFO3Controller_changed()
1135 {
1136 int rowno = eLFO3Controller.get_active_row_number();
1137 eLFO3ControlDepth.set_sensitive(rowno != 0);
1138 eLFO3InternalDepth.set_sensitive(rowno != 1 && rowno != 2);
1139 }
1140
1141 void MainWindow::crossfade1_changed()
1142 {
1143 double c1 = eCrossfade_in_start.get_value();
1144 double c2 = eCrossfade_in_end.get_value();
1145 if (c1 > c2) eCrossfade_in_end.set_value(c1);
1146 }
1147
1148 void MainWindow::crossfade2_changed()
1149 {
1150 double c1 = eCrossfade_in_start.get_value();
1151 double c2 = eCrossfade_in_end.get_value();
1152 double c3 = eCrossfade_out_start.get_value();
1153
1154 if (c2 < c1) eCrossfade_in_start.set_value(c2);
1155 if (c2 > c3) eCrossfade_out_start.set_value(c2);
1156 }
1157
1158 void MainWindow::crossfade3_changed()
1159 {
1160 double c2 = eCrossfade_in_end.get_value();
1161 double c3 = eCrossfade_out_start.get_value();
1162 double c4 = eCrossfade_out_end.get_value();
1163
1164 if (c3 < c2) eCrossfade_in_end.set_value(c3);
1165 if (c3 > c4) eCrossfade_out_end.set_value(c3);
1166 }
1167
1168 void MainWindow::crossfade4_changed()
1169 {
1170 double c3 = eCrossfade_out_start.get_value();
1171 double c4 = eCrossfade_out_end.get_value();
1172
1173 if (c4 < c3) eCrossfade_out_start.set_value(c4);
1174 }
1175
1176 void loader_progress_callback(gig::progress_t* progress)
1177 {
1178 Loader* loader = static_cast<Loader*>(progress->custom);
1179 loader->progress_callback(progress->factor);
1180 }
1181
1182 void Loader::progress_callback(float fraction)
1183 {
1184 {
1185 Glib::Mutex::Lock lock(progressMutex);
1186 progress = fraction;
1187 }
1188 progress_dispatcher();
1189 }
1190
1191 void Loader::thread_function()
1192 {
1193 printf("thread_function self=%x\n", Glib::Thread::self());
1194 printf("Start %s\n", filename);
1195 RIFF::File* riff = new RIFF::File(filename);
1196 gig = new gig::File(riff);
1197 gig::progress_t progress;
1198 progress.callback = loader_progress_callback;
1199 progress.custom = this;
1200
1201 gig->GetInstrument(0, &progress);
1202 printf("End\n");
1203 finished_dispatcher();
1204 }
1205
1206 Loader::Loader(const char* filename)
1207 : thread(0), filename(filename)
1208 {
1209 }
1210
1211 void Loader::launch()
1212 {
1213 thread = Glib::Thread::create(sigc::mem_fun(*this, &Loader::thread_function), true);
1214 printf("launch thread=%x\n", thread);
1215 }
1216
1217 float Loader::get_progress()
1218 {
1219 float res;
1220 {
1221 Glib::Mutex::Lock lock(progressMutex);
1222 res = progress;
1223 }
1224 return res;
1225 }
1226
1227 Glib::Dispatcher& Loader::signal_progress()
1228 {
1229 return progress_dispatcher;
1230 }
1231
1232 Glib::Dispatcher& Loader::signal_finished()
1233 {
1234 return finished_dispatcher;
1235 }
1236
1237 LoadDialog::LoadDialog()
1238 {
1239 get_vbox()->pack_start(progressBar);
1240 show_all_children();
1241 }
1242
1243 void MainWindow::on_action_file_new()
1244 {
1245 }
1246
1247 void MainWindow::on_action_file_open()
1248 {
1249 Gtk::FileChooserDialog dialog(*this, _("Open file"));
1250 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1251 dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1252 Gtk::FileFilter filter;
1253 filter.add_pattern("*.gig");
1254 dialog.set_filter(filter);
1255 if (dialog.run() == Gtk::RESPONSE_OK) {
1256 printf("filename=%s\n", dialog.get_filename().c_str());
1257
1258 // remove all entries from "Instrument" menu
1259 Gtk::MenuItem* instrument_menu =
1260 dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/MenuBar/MenuInstrument"));
1261 instrument_menu->hide();
1262 for (int i = 0; i < instrument_menu->get_submenu()->items().size(); i++) {
1263 delete &instrument_menu->get_submenu()->items()[i];
1264 }
1265 instrument_menu->get_submenu()->items().clear();
1266
1267 m_refTreeModel->clear();
1268 m_refSamplesTreeModel->clear();
1269 if (file) delete file;
1270
1271 // getInfo(dialog.get_filename().c_str(), *this);
1272
1273 printf("on_action_file_open self=%x\n", Glib::Thread::self());
1274 load_dialog = new LoadDialog(); // Gtk::Dialog("Loading...", *this, true);
1275 load_dialog->show_all();
1276 loader = new Loader(strdup(dialog.get_filename().c_str()));
1277 loader->signal_progress().connect(
1278 sigc::mem_fun(*this, &MainWindow::on_loader_progress));
1279 loader->signal_finished().connect(
1280 sigc::mem_fun(*this, &MainWindow::on_loader_finished));
1281
1282 loader->launch();
1283 }
1284 }
1285
1286 void MainWindow::on_loader_progress()
1287 {
1288 load_dialog->set_fraction(loader->get_progress());
1289 }
1290
1291 void MainWindow::on_loader_finished()
1292 {
1293 printf("Loader finished!\n");
1294 printf("on_loader_finished self=%x\n", Glib::Thread::self());
1295 load_gig(loader->gig, loader->filename);
1296
1297
1298 Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
1299 tree_sel_ref->select(Gtk::TreePath("0"));
1300
1301 load_dialog->hide();
1302 }
1303
1304 void MainWindow::on_action_file_save()
1305 {
1306 }
1307
1308 void MainWindow::on_action_file_save_as()
1309 {
1310 Gtk::FileChooserDialog dialog(*this, "Open", Gtk::FILE_CHOOSER_ACTION_SAVE);
1311 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1312 dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
1313 Gtk::FileFilter filter;
1314 filter.add_pattern("*.gig");
1315 dialog.set_filter(filter);
1316 if (dialog.run() == Gtk::RESPONSE_OK) {
1317 printf("filename=%s\n", dialog.get_filename().c_str());
1318 file->Save(dialog.get_filename());
1319 }
1320 }
1321
1322 void MainWindow::on_action_file_properties()
1323 {
1324 propDialog.show();
1325 propDialog.deiconify();
1326 }
1327
1328 void MainWindow::on_action_help_about()
1329 {
1330 #ifdef ABOUT_DIALOG
1331 Gtk::AboutDialog dialog;
1332 dialog.set_version(VERSION);
1333 dialog.run();
1334 #endif
1335 }
1336
1337 PropDialog::PropDialog()
1338 : table(2,1)
1339 {
1340 table.set_col_spacings(5);
1341 char* propLabels[] = {
1342 "Name:",
1343 "CreationDate:",
1344 "Comments:", // TODO: multiline
1345 "Product:",
1346 "Copyright:",
1347 "Artists:",
1348 "Genre:",
1349 "Keywords:",
1350 "Engineer:",
1351 "Technician:",
1352 "Software:", // TODO: readonly
1353 "Medium:",
1354 "Source:",
1355 "SourceForm:",
1356 "Commissioned:",
1357 "Subject:"
1358 };
1359 for (int i = 0 ; i < sizeof(propLabels) / sizeof(char*) ; i++) {
1360 label[i].set_text(propLabels[i]);
1361 label[i].set_alignment(Gtk::ALIGN_LEFT);
1362 table.attach(label[i], 0, 1, i, i + 1, Gtk::FILL, Gtk::SHRINK);
1363 table.attach(entry[i], 1, 2, i, i + 1, Gtk::FILL | Gtk::EXPAND,
1364 Gtk::SHRINK);
1365 }
1366
1367 add(table);
1368 // add_button(Gtk::Stock::CANCEL, 0);
1369 // add_button(Gtk::Stock::OK, 1);
1370 show_all_children();
1371 }
1372
1373 void PropDialog::set_info(DLS::Info* info)
1374 {
1375 entry[0].set_text(info->Name);
1376 entry[1].set_text(info->CreationDate);
1377 entry[2].set_text(Glib::convert(info->Comments, "UTF-8", "ISO-8859-1"));
1378 entry[3].set_text(info->Product);
1379 entry[4].set_text(info->Copyright);
1380 entry[5].set_text(info->Artists);
1381 entry[6].set_text(info->Genre);
1382 entry[7].set_text(info->Keywords);
1383 entry[8].set_text(info->Engineer);
1384 entry[9].set_text(info->Technician);
1385 entry[10].set_text(info->Software);
1386 entry[11].set_text(info->Medium);
1387 entry[12].set_text(info->Source);
1388 entry[13].set_text(info->SourceForm);
1389 entry[14].set_text(info->Commissioned);
1390 entry[15].set_text(info->Subject);
1391 }
1392
1393
1394 InstrumentProps::InstrumentProps()
1395 : table(2,1),
1396 quitButton(Gtk::Stock::CLOSE)
1397 {
1398 table.set_col_spacings(5);
1399 char* propLabels[] = {
1400 "Name:",
1401 "IsDrum:",
1402 "MIDIBank:",
1403 "MIDIProgram:",
1404 "Attenuation:",
1405 "EffectSend:",
1406 "FineTune:",
1407 "PitchbendRange:",
1408 "PianoReleaseMode:",
1409 "DimensionKeyRange:",
1410 };
1411 int entryIdx = 0, checkIdx = 0;
1412 for (int i = 0 ; i < sizeof(propLabels) / sizeof(char*) ; i++) {
1413 label[i].set_text(propLabels[i]);
1414 label[i].set_alignment(Gtk::ALIGN_LEFT);
1415 table.attach(label[i], 0, 1, i, i + 1, Gtk::FILL, Gtk::SHRINK);
1416 if (i == 1 || i == 8)
1417 table.attach(check[checkIdx++], 1, 2, i, i + 1,
1418 Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
1419 else
1420 table.attach(entry[entryIdx++], 1, 2, i, i + 1,
1421 Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
1422 }
1423
1424 // vbox { table buttonBox { quitButton } }
1425
1426 //get_vbox()->pack_start(table);
1427 // set_border_width(6);
1428 add(vbox);
1429 table.set_border_width(2);
1430 vbox.pack_start(table);
1431 table.show();
1432 vbox.pack_start(buttonBox);
1433 buttonBox.set_layout(Gtk::BUTTONBOX_END);
1434 buttonBox.set_border_width(5);
1435 buttonBox.show();
1436 buttonBox.pack_start(quitButton);
1437 quitButton.set_flags(Gtk::CAN_DEFAULT);
1438 quitButton.grab_focus();
1439
1440 quitButton.signal_clicked().connect(
1441 sigc::mem_fun(*this, &InstrumentProps::hide));
1442
1443 // quitButton.grab_default();
1444 quitButton.show();
1445 // add(table);
1446 vbox.show();
1447 show_all_children();
1448 }
1449
1450
1451 void InstrumentProps::set_instrument(gig::Instrument* instrument)
1452 {
1453 char buf[100];
1454
1455 int entryIdx = 0, checkIdx = 0;
1456 entry[entryIdx++].set_text(instrument->pInfo->Name);
1457 check[checkIdx++].set_active(instrument->IsDrum);
1458 sprintf(buf, "%d", instrument->MIDIBank);
1459 entry[entryIdx++].set_text(buf);
1460 sprintf(buf, "%d", instrument->MIDIProgram);
1461 entry[entryIdx++].set_text(buf);
1462 sprintf(buf, "%d", instrument->Attenuation);
1463 entry[entryIdx++].set_text(buf);
1464 sprintf(buf, "%d", instrument->EffectSend);
1465 entry[entryIdx++].set_text(buf);
1466 sprintf(buf, "%d", instrument->FineTune);
1467 entry[entryIdx++].set_text(buf);
1468 sprintf(buf, "%d", instrument->PitchbendRange);
1469 entry[entryIdx++].set_text(buf);
1470 check[checkIdx++].set_active(instrument->PianoReleaseMode);
1471 sprintf(buf, "%s%d (%d)..%s%d (%d)",
1472 notes[instrument->DimensionKeyRange.low % 12],
1473 instrument->DimensionKeyRange.low / 12 - 1,
1474 instrument->DimensionKeyRange.low,
1475 notes[instrument->DimensionKeyRange.high % 12],
1476 instrument->DimensionKeyRange.high / 12 - 1,
1477 instrument->DimensionKeyRange.high);
1478 entry[entryIdx].set_text(buf);
1479 }
1480
1481 void MainWindow::getInfo(const char *filename)
1482 {
1483 RIFF::File* riff = new RIFF::File(filename);
1484 gig::File* gig = new gig::File(riff);
1485
1486 load_gig(gig, filename);
1487 }
1488
1489 void MainWindow::load_gig(gig::File* gig, const char* filename)
1490 {
1491 file = gig;
1492
1493 const char *basename = strrchr(filename, '/');
1494 basename = basename ? basename + 1 : filename;
1495
1496 set_title(basename);
1497
1498 propDialog.set_info(gig->pInfo);
1499
1500 Gtk::MenuItem* instrument_menu =
1501 dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/MenuBar/MenuInstrument"));
1502
1503 int instrument_index = 0;
1504 Gtk::RadioMenuItem::Group instrument_group;
1505 for (gig::Instrument* instrument = gig->GetFirstInstrument() ; instrument ;
1506 instrument = gig->GetNextInstrument()) {
1507 Gtk::TreeModel::iterator iter = m_refTreeModel->append();
1508 Gtk::TreeModel::Row row = *iter;
1509 row[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();
1510 row[m_Columns.m_col_instr] = instrument;
1511 // create a menu item for this instrument
1512 Gtk::RadioMenuItem* item= new Gtk::RadioMenuItem(instrument_group, instrument->pInfo->Name.c_str());
1513 instrument_menu->get_submenu()->append(*item);
1514 item->signal_activate().connect(
1515 sigc::bind(
1516 sigc::mem_fun(*this, &MainWindow::on_instrument_selection_change),
1517 instrument_index
1518 )
1519 );
1520 instrument_index++;
1521 }
1522 instrument_menu->show();
1523 instrument_menu->get_submenu()->show_all_children();
1524
1525 for (gig::Group* group = gig->GetFirstGroup(); group; group = gig->GetNextGroup()) {
1526 Gtk::TreeModel::iterator iterGroup = m_refSamplesTreeModel->append();
1527 Gtk::TreeModel::Row rowGroup = *iterGroup;
1528 rowGroup[m_SamplesModel.m_col_name] = group->Name.c_str();
1529 rowGroup[m_SamplesModel.m_col_sample] = group;
1530 for (gig::Sample* sample = group->GetFirstSample(); sample; sample = group->GetNextSample()) {
1531 Gtk::TreeModel::iterator iterSample = m_refSamplesTreeModel->append(rowGroup.children());
1532 Gtk::TreeModel::Row rowSample = *iterSample;
1533 rowSample[m_SamplesModel.m_col_name] = sample->pInfo->Name.c_str();
1534 rowSample[m_SamplesModel.m_col_sample] = sample;
1535 }
1536 }
1537 }
1538
1539 void MainWindow::on_button_release(GdkEventButton* button)
1540 {
1541 if (button->type == GDK_2BUTTON_PRESS) {
1542 Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
1543 Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();
1544 if (it)
1545 {
1546 Gtk::TreeModel::Row row = *it;
1547 if (row[m_Columns.m_col_instr])
1548 {
1549 instrumentProps.set_instrument(row[m_Columns.m_col_instr]);
1550 instrumentProps.show();
1551 instrumentProps.deiconify();
1552 }
1553 }
1554 } else if (button->type == GDK_BUTTON_PRESS && button->button == 3) {
1555 popup_menu->popup(button->button, button->time);
1556 }
1557 }
1558
1559 void MainWindow::on_instrument_selection_change(int index) {
1560 m_RegionChooser.set_instrument(file->GetInstrument(index));
1561 }

  ViewVC Help
Powered by ViewVC