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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1084 - (show annotations) (download)
Thu Mar 8 16:47:15 2007 UTC (14 years, 6 months ago) by schoenebeck
File size: 58863 byte(s)
* implemented "Remove" operation in right-click popup on
  samples and groups (in samples tree view)
  Note: you need latest CVS version of libgig for this to work!

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

  ViewVC Help
Powered by ViewVC