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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1069 - (show annotations) (download)
Sun Mar 4 22:00:46 2007 UTC (13 years, 4 months ago) by schoenebeck
File size: 53053 byte(s)
* added new Menu "Instruments" where one of the loaded .gig files
  instrument can be selected (note: this Menu only appears when a .gig file
  is loaded)

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, inside a ScrolledWindow, with the button underneath:
527 m_ScrolledWindow.add(m_TreeView);
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 actionGroup = Gtk::ActionGroup::create();
787
788 actionGroup->add(Gtk::Action::create("MenuFile", _("_File")));
789 actionGroup->add(Gtk::Action::create("New", Gtk::Stock::NEW),
790 sigc::mem_fun(
791 *this, &MainWindow::on_action_file_new));
792 Glib::RefPtr<Gtk::Action> action =
793 Gtk::Action::create("Open", Gtk::Stock::OPEN);
794 action->property_label() = action->property_label() + "...";
795 actionGroup->add(action,
796 sigc::mem_fun(
797 *this, &MainWindow::on_action_file_open));
798 actionGroup->add(Gtk::Action::create("Save", Gtk::Stock::SAVE),
799 sigc::mem_fun(
800 *this, &MainWindow::on_action_file_save));
801 action = Gtk::Action::create("SaveAs", Gtk::Stock::SAVE_AS);
802 action->property_label() = action->property_label() + "...";
803 actionGroup->add(action,
804 *(new Gtk::AccelKey("<shift><control>s")),
805 sigc::mem_fun(
806 *this, &MainWindow::on_action_file_save_as)
807 );
808 actionGroup->add(Gtk::Action::create("Properties",
809 Gtk::Stock::PROPERTIES),
810 sigc::mem_fun(
811 *this, &MainWindow::on_action_file_properties));
812 actionGroup->add(Gtk::Action::create("InstrProperties",
813 Gtk::Stock::PROPERTIES),
814 sigc::mem_fun(
815 *this, &MainWindow::on_action_file_properties));
816 actionGroup->add(Gtk::Action::create("Quit", Gtk::Stock::QUIT),
817 sigc::mem_fun(
818 *this, &MainWindow::hide));
819 actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));
820
821 action = Gtk::Action::create("MenuHelp", Gtk::Stock::HELP);
822 actionGroup->add(Gtk::Action::create("MenuHelp",
823 action->property_label()));
824 #ifdef ABOUT_DIALOG
825 actionGroup->add(Gtk::Action::create("About", Gtk::Stock::ABOUT),
826 sigc::mem_fun(
827 *this, &MainWindow::on_action_help_about));
828 #endif
829 action = Gtk::Action::create("Remove", "Ta bort");
830 actionGroup->add(action,
831 sigc::mem_fun(
832 *this, &MainWindow::hide));
833
834 uiManager = Gtk::UIManager::create();
835 uiManager->insert_action_group(actionGroup);
836 // add_accel_group(uiManager->get_accel_group());
837
838 Glib::ustring ui_info =
839 "<ui>"
840 " <menubar name='MenuBar'>"
841 " <menu action='MenuFile'>"
842 " <menuitem action='New'/>"
843 " <menuitem action='Open'/>"
844 " <separator/>"
845 " <menuitem action='Save'/>"
846 " <menuitem action='SaveAs'/>"
847 " <separator/>"
848 " <menuitem action='Properties'/>"
849 " <separator/>"
850 " <menuitem action='Quit'/>"
851 " </menu>"
852 " <menu action='MenuInstrument'>"
853 " </menu>"
854 #ifdef ABOUT_DIALOG
855 " <menu action='MenuHelp'>"
856 " <menuitem action='About'/>"
857 " </menu>"
858 #endif
859 " </menubar>"
860 " <popup name='PopupMenu'>"
861 " <menuitem action='InstrProperties'/>"
862 " <menuitem action='Remove'/>"
863 " </popup>"
864 "</ui>";
865 uiManager->add_ui_from_string(ui_info);
866
867 popup_menu = dynamic_cast<Gtk::Menu*>(uiManager->get_widget("/PopupMenu"));
868
869 Gtk::Widget* menuBar = uiManager->get_widget("/MenuBar");
870 m_VBox.pack_start(*menuBar, Gtk::PACK_SHRINK);
871 m_VBox.pack_start(m_HPaned);
872 m_VBox.pack_start(m_RegionChooser, Gtk::PACK_SHRINK);
873 m_VBox.pack_start(m_DimRegionChooser, Gtk::PACK_SHRINK);
874
875 m_RegionChooser.signal_sel_changed().connect(
876 sigc::mem_fun(*this, &MainWindow::region_changed) );
877 m_DimRegionChooser.signal_sel_changed().connect(
878 sigc::mem_fun(*this, &MainWindow::dimreg_changed) );
879
880
881 // Create the Tree model:
882 m_refTreeModel = Gtk::ListStore::create(m_Columns);
883 m_TreeView.set_model(m_refTreeModel);
884
885 // Add the TreeView's view columns:
886 m_TreeView.append_column("Instrument", m_Columns.m_col_name);
887 m_TreeView.set_headers_visible(false);
888
889 file = 0;
890
891 show_all_children();
892 }
893
894 MainWindow::~MainWindow()
895 {
896 }
897
898 void MainWindow::region_changed()
899 {
900 m_DimRegionChooser.set_region(m_RegionChooser.get_region());
901 }
902
903 void MainWindow::dimreg_changed()
904 {
905 set_dim_region(m_DimRegionChooser.get_dimregion());
906 }
907
908 void MainWindow::on_sel_change()
909 {
910 Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
911
912 Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();
913 if (it)
914 {
915 Gtk::TreeModel::Row row = *it;
916 std::cout << row[m_Columns.m_col_name] << std::endl;
917
918 if (row[m_Columns.m_col_instr])
919 m_RegionChooser.set_instrument(row[m_Columns.m_col_instr]);
920 }
921 }
922
923 void MainWindow::set_dim_region(gig::DimensionRegion* d)
924 {
925 update_gui = false;
926 wSample->set_text(d->pSample ? d->pSample->pInfo->Name.c_str() : "NULL");
927 eVelocityUpperLimit.set_dimreg(d);
928 eEG1PreAttack.set_dimreg(d);
929 eEG1Attack.set_dimreg(d);
930 eEG1Decay1.set_dimreg(d);
931 eEG1Decay2.set_dimreg(d);
932 eEG1InfiniteSustain.set_dimreg(d);
933 eEG1Sustain.set_dimreg(d);
934 eEG1Release.set_dimreg(d);
935 eEG1Hold.set_dimreg(d);
936 eEG1Controller.set_dimreg(d);
937 eEG1ControllerInvert.set_dimreg(d);
938 eEG1ControllerAttackInfluence.set_dimreg(d);
939 eEG1ControllerDecayInfluence.set_dimreg(d);
940 eEG1ControllerReleaseInfluence.set_dimreg(d);
941 eLFO1Frequency.set_dimreg(d);
942 eLFO1InternalDepth.set_dimreg(d);
943 eLFO1ControlDepth.set_dimreg(d);
944 eLFO1Controller.set_dimreg(d);
945 eLFO1FlipPhase.set_dimreg(d);
946 eLFO1Sync.set_dimreg(d);
947 eEG2PreAttack.set_dimreg(d);
948 eEG2Attack.set_dimreg(d);
949 eEG2Decay1.set_dimreg(d);
950 eEG2Decay2.set_dimreg(d);
951 eEG2InfiniteSustain.set_dimreg(d);
952 eEG2Sustain.set_dimreg(d);
953 eEG2Release.set_dimreg(d);
954 eEG2Controller.set_dimreg(d);
955 eEG2ControllerInvert.set_dimreg(d);
956 eEG2ControllerAttackInfluence.set_dimreg(d);
957 eEG2ControllerDecayInfluence.set_dimreg(d);
958 eEG2ControllerReleaseInfluence.set_dimreg(d);
959 eLFO2Frequency.set_dimreg(d);
960 eLFO2InternalDepth.set_dimreg(d);
961 eLFO2ControlDepth.set_dimreg(d);
962 eLFO2Controller.set_dimreg(d);
963 eLFO2FlipPhase.set_dimreg(d);
964 eLFO2Sync.set_dimreg(d);
965 eEG3Attack.set_dimreg(d);
966 eEG3Depth.set_dimreg(d);
967 eLFO3Frequency.set_dimreg(d);
968 eLFO3InternalDepth.set_dimreg(d);
969 eLFO3ControlDepth.set_dimreg(d);
970 eLFO3Controller.set_dimreg(d);
971 eLFO3Sync.set_dimreg(d);
972 eVCFEnabled.set_dimreg(d);
973 eVCFType.set_dimreg(d);
974 eVCFCutoffController.set_dimreg(d);
975 eVCFCutoffControllerInvert.set_dimreg(d);
976 eVCFCutoff.set_dimreg(d);
977 eVCFVelocityCurve.set_dimreg(d);
978 eVCFVelocityScale.set_dimreg(d);
979 eVCFVelocityDynamicRange.set_dimreg(d);
980 eVCFResonance.set_dimreg(d);
981 eVCFResonanceDynamic.set_dimreg(d);
982 eVCFResonanceController.set_dimreg(d);
983 eVCFKeyboardTracking.set_dimreg(d);
984 eVCFKeyboardTrackingBreakpoint.set_dimreg(d);
985 eVelocityResponseCurve.set_dimreg(d);
986 eVelocityResponseDepth.set_dimreg(d);
987 eVelocityResponseCurveScaling.set_dimreg(d);
988 eReleaseVelocityResponseCurve.set_dimreg(d);
989 eReleaseVelocityResponseDepth.set_dimreg(d);
990 eReleaseTriggerDecay.set_dimreg(d);
991 eCrossfade_in_start.set_dimreg(d);
992 eCrossfade_in_end.set_dimreg(d);
993 eCrossfade_out_start.set_dimreg(d);
994 eCrossfade_out_end.set_dimreg(d);
995 ePitchTrack.set_dimreg(d);
996 eDimensionBypass.set_dimreg(d);
997 ePan.set_dimreg(d);
998 eSelfMask.set_dimreg(d);
999 eAttenuationController.set_dimreg(d);
1000 eInvertAttenuationController.set_dimreg(d);
1001 eAttenuationControllerThreshold.set_dimreg(d);
1002 eChannelOffset.set_dimreg(d);
1003 eSustainDefeat.set_dimreg(d);
1004 eMSDecode.set_dimreg(d);
1005 eSampleStartOffset.set_dimreg(d);
1006 eUnityNote.set_dimreg(d);
1007 eFineTune.set_dimreg(d);
1008 eGain.set_dimreg(d);
1009 eSampleLoops.set_dimreg(d);
1010
1011 VCFEnabled_toggled();
1012
1013 update_gui = true;
1014 }
1015
1016 void MainWindow::VCFEnabled_toggled()
1017 {
1018 bool sensitive = eVCFEnabled.get_active();
1019 eVCFType.set_sensitive(sensitive);
1020 eVCFCutoffController.set_sensitive(sensitive);
1021 eVCFVelocityCurve.set_sensitive(sensitive);
1022 eVCFVelocityScale.set_sensitive(sensitive);
1023 eVCFVelocityDynamicRange.set_sensitive(sensitive);
1024 eVCFResonance.set_sensitive(sensitive);
1025 eVCFResonanceController.set_sensitive(sensitive);
1026 eVCFKeyboardTracking.set_sensitive(sensitive);
1027 eVCFKeyboardTrackingBreakpoint.set_sensitive(sensitive);
1028 eEG2PreAttack.set_sensitive(sensitive);
1029 eEG2Attack.set_sensitive(sensitive);
1030 eEG2Decay1.set_sensitive(sensitive);
1031 eEG2InfiniteSustain.set_sensitive(sensitive);
1032 eEG2Sustain.set_sensitive(sensitive);
1033 eEG2Release.set_sensitive(sensitive);
1034 eEG2Controller.set_sensitive(sensitive);
1035 eEG2ControllerAttackInfluence.set_sensitive(sensitive);
1036 eEG2ControllerDecayInfluence.set_sensitive(sensitive);
1037 eEG2ControllerReleaseInfluence.set_sensitive(sensitive);
1038 eLFO2Frequency.set_sensitive(sensitive);
1039 eLFO2InternalDepth.set_sensitive(sensitive);
1040 eLFO2ControlDepth.set_sensitive(sensitive);
1041 eLFO2Controller.set_sensitive(sensitive);
1042 eLFO2FlipPhase.set_sensitive(sensitive);
1043 eLFO2Sync.set_sensitive(sensitive);
1044 if (sensitive) {
1045 VCFCutoffController_changed();
1046 VCFResonanceController_changed();
1047 EG2InfiniteSustain_toggled();
1048 EG2Controller_changed();
1049 LFO2Controller_changed();
1050 } else {
1051 eVCFCutoffControllerInvert.set_sensitive(false);
1052 eVCFCutoff.set_sensitive(false);
1053 eVCFResonanceDynamic.set_sensitive(false);
1054 eVCFResonance.set_sensitive(false);
1055 eEG2Decay2.set_sensitive(false);
1056 eEG2ControllerInvert.set_sensitive(false);
1057 eLFO2InternalDepth.set_sensitive(false);
1058 eLFO2ControlDepth.set_sensitive(false);
1059 }
1060 }
1061
1062 void MainWindow::VCFCutoffController_changed()
1063 {
1064 int rowno = eVCFCutoffController.get_active_row_number();
1065 bool hasController = rowno != 0 && rowno != 1;
1066
1067 eVCFCutoffControllerInvert.set_sensitive(hasController);
1068 eVCFCutoff.set_sensitive(!hasController);
1069 eVCFResonanceDynamic.set_sensitive(!hasController);
1070 eVCFVelocityScale.label.set_text(hasController ? "MinimumCutoff:" :
1071 "VelocityScale:");
1072 }
1073
1074 void MainWindow::VCFResonanceController_changed()
1075 {
1076 bool hasController = eVCFResonanceController.get_active_row_number() != 0;
1077 eVCFResonance.set_sensitive(!hasController);
1078 }
1079
1080 void MainWindow::EG1InfiniteSustain_toggled()
1081 {
1082 bool infSus = eEG1InfiniteSustain.get_active();
1083 eEG1Decay2.set_sensitive(!infSus);
1084 }
1085
1086 void MainWindow::EG2InfiniteSustain_toggled()
1087 {
1088 bool infSus = eEG2InfiniteSustain.get_active();
1089 eEG2Decay2.set_sensitive(!infSus);
1090 }
1091
1092 void MainWindow::EG1Controller_changed()
1093 {
1094 bool hasController = eEG1Controller.get_active_row_number() != 0;
1095 eEG1ControllerInvert.set_sensitive(hasController);
1096 }
1097
1098 void MainWindow::EG2Controller_changed()
1099 {
1100 bool hasController = eEG2Controller.get_active_row_number() != 0;
1101 eEG2ControllerInvert.set_sensitive(hasController);
1102 }
1103
1104 void MainWindow::AttenuationController_changed()
1105 {
1106 bool hasController = eAttenuationController.get_active_row_number() != 0;
1107 eInvertAttenuationController.set_sensitive(hasController);
1108 }
1109
1110 void MainWindow::LFO1Controller_changed()
1111 {
1112 int rowno = eLFO1Controller.get_active_row_number();
1113 eLFO1ControlDepth.set_sensitive(rowno != 0);
1114 eLFO1InternalDepth.set_sensitive(rowno != 1 && rowno != 2);
1115 }
1116
1117 void MainWindow::LFO2Controller_changed()
1118 {
1119 int rowno = eLFO2Controller.get_active_row_number();
1120 eLFO2ControlDepth.set_sensitive(rowno != 0);
1121 eLFO2InternalDepth.set_sensitive(rowno != 1 && rowno != 2);
1122 }
1123
1124 void MainWindow::LFO3Controller_changed()
1125 {
1126 int rowno = eLFO3Controller.get_active_row_number();
1127 eLFO3ControlDepth.set_sensitive(rowno != 0);
1128 eLFO3InternalDepth.set_sensitive(rowno != 1 && rowno != 2);
1129 }
1130
1131 void MainWindow::crossfade1_changed()
1132 {
1133 double c1 = eCrossfade_in_start.get_value();
1134 double c2 = eCrossfade_in_end.get_value();
1135 if (c1 > c2) eCrossfade_in_end.set_value(c1);
1136 }
1137
1138 void MainWindow::crossfade2_changed()
1139 {
1140 double c1 = eCrossfade_in_start.get_value();
1141 double c2 = eCrossfade_in_end.get_value();
1142 double c3 = eCrossfade_out_start.get_value();
1143
1144 if (c2 < c1) eCrossfade_in_start.set_value(c2);
1145 if (c2 > c3) eCrossfade_out_start.set_value(c2);
1146 }
1147
1148 void MainWindow::crossfade3_changed()
1149 {
1150 double c2 = eCrossfade_in_end.get_value();
1151 double c3 = eCrossfade_out_start.get_value();
1152 double c4 = eCrossfade_out_end.get_value();
1153
1154 if (c3 < c2) eCrossfade_in_end.set_value(c3);
1155 if (c3 > c4) eCrossfade_out_end.set_value(c3);
1156 }
1157
1158 void MainWindow::crossfade4_changed()
1159 {
1160 double c3 = eCrossfade_out_start.get_value();
1161 double c4 = eCrossfade_out_end.get_value();
1162
1163 if (c4 < c3) eCrossfade_out_start.set_value(c4);
1164 }
1165
1166 void loader_progress_callback(gig::progress_t* progress)
1167 {
1168 Loader* loader = static_cast<Loader*>(progress->custom);
1169 loader->progress_callback(progress->factor);
1170 }
1171
1172 void Loader::progress_callback(float fraction)
1173 {
1174 {
1175 Glib::Mutex::Lock lock(progressMutex);
1176 progress = fraction;
1177 }
1178 progress_dispatcher();
1179 }
1180
1181 void Loader::thread_function()
1182 {
1183 printf("thread_function self=%x\n", Glib::Thread::self());
1184 printf("Start %s\n", filename);
1185 RIFF::File* riff = new RIFF::File(filename);
1186 gig = new gig::File(riff);
1187 gig::progress_t progress;
1188 progress.callback = loader_progress_callback;
1189 progress.custom = this;
1190
1191 gig->GetInstrument(0, &progress);
1192 printf("End\n");
1193 finished_dispatcher();
1194 }
1195
1196 Loader::Loader(const char* filename)
1197 : thread(0), filename(filename)
1198 {
1199 }
1200
1201 void Loader::launch()
1202 {
1203 thread = Glib::Thread::create(sigc::mem_fun(*this, &Loader::thread_function), true);
1204 printf("launch thread=%x\n", thread);
1205 }
1206
1207 float Loader::get_progress()
1208 {
1209 float res;
1210 {
1211 Glib::Mutex::Lock lock(progressMutex);
1212 res = progress;
1213 }
1214 return res;
1215 }
1216
1217 Glib::Dispatcher& Loader::signal_progress()
1218 {
1219 return progress_dispatcher;
1220 }
1221
1222 Glib::Dispatcher& Loader::signal_finished()
1223 {
1224 return finished_dispatcher;
1225 }
1226
1227 LoadDialog::LoadDialog()
1228 {
1229 get_vbox()->pack_start(progressBar);
1230 show_all_children();
1231 }
1232
1233 void MainWindow::on_action_file_new()
1234 {
1235 }
1236
1237 void MainWindow::on_action_file_open()
1238 {
1239 Gtk::FileChooserDialog dialog(*this, _("Open file"));
1240 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1241 dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1242 Gtk::FileFilter filter;
1243 filter.add_pattern("*.gig");
1244 dialog.set_filter(filter);
1245 if (dialog.run() == Gtk::RESPONSE_OK) {
1246 printf("filename=%s\n", dialog.get_filename().c_str());
1247
1248 // remove all entries from "Instrument" menu
1249 Gtk::MenuItem* instrument_menu =
1250 dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/MenuBar/MenuInstrument"));
1251 instrument_menu->hide();
1252 for (int i = 0; i < instrument_menu->get_submenu()->items().size(); i++) {
1253 delete &instrument_menu->get_submenu()->items()[i];
1254 }
1255 instrument_menu->get_submenu()->items().clear();
1256
1257 m_refTreeModel->clear();
1258 if (file) delete file;
1259
1260 // getInfo(dialog.get_filename().c_str(), *this);
1261
1262 printf("on_action_file_open self=%x\n", Glib::Thread::self());
1263 load_dialog = new LoadDialog(); // Gtk::Dialog("Loading...", *this, true);
1264 load_dialog->show_all();
1265 loader = new Loader(strdup(dialog.get_filename().c_str()));
1266 loader->signal_progress().connect(
1267 sigc::mem_fun(*this, &MainWindow::on_loader_progress));
1268 loader->signal_finished().connect(
1269 sigc::mem_fun(*this, &MainWindow::on_loader_finished));
1270
1271 loader->launch();
1272 }
1273 }
1274
1275 void MainWindow::on_loader_progress()
1276 {
1277 load_dialog->set_fraction(loader->get_progress());
1278 }
1279
1280 void MainWindow::on_loader_finished()
1281 {
1282 printf("Loader finished!\n");
1283 printf("on_loader_finished self=%x\n", Glib::Thread::self());
1284 load_gig(loader->gig, loader->filename);
1285
1286
1287 Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
1288 tree_sel_ref->select(Gtk::TreePath("0"));
1289
1290 load_dialog->hide();
1291 }
1292
1293 void MainWindow::on_action_file_save()
1294 {
1295 }
1296
1297 void MainWindow::on_action_file_save_as()
1298 {
1299 Gtk::FileChooserDialog dialog(*this, "Open", Gtk::FILE_CHOOSER_ACTION_SAVE);
1300 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1301 dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
1302 Gtk::FileFilter filter;
1303 filter.add_pattern("*.gig");
1304 dialog.set_filter(filter);
1305 if (dialog.run() == Gtk::RESPONSE_OK) {
1306 printf("filename=%s\n", dialog.get_filename().c_str());
1307 file->Save(dialog.get_filename());
1308 }
1309 }
1310
1311 void MainWindow::on_action_file_properties()
1312 {
1313 propDialog.show();
1314 propDialog.deiconify();
1315 }
1316
1317 void MainWindow::on_action_help_about()
1318 {
1319 #ifdef ABOUT_DIALOG
1320 Gtk::AboutDialog dialog;
1321 dialog.set_version(VERSION);
1322 dialog.run();
1323 #endif
1324 }
1325
1326 PropDialog::PropDialog()
1327 : table(2,1)
1328 {
1329 table.set_col_spacings(5);
1330 char* propLabels[] = {
1331 "Name:",
1332 "CreationDate:",
1333 "Comments:", // TODO: multiline
1334 "Product:",
1335 "Copyright:",
1336 "Artists:",
1337 "Genre:",
1338 "Keywords:",
1339 "Engineer:",
1340 "Technician:",
1341 "Software:", // TODO: readonly
1342 "Medium:",
1343 "Source:",
1344 "SourceForm:",
1345 "Commissioned:",
1346 "Subject:"
1347 };
1348 for (int i = 0 ; i < sizeof(propLabels) / sizeof(char*) ; i++) {
1349 label[i].set_text(propLabels[i]);
1350 label[i].set_alignment(Gtk::ALIGN_LEFT);
1351 table.attach(label[i], 0, 1, i, i + 1, Gtk::FILL, Gtk::SHRINK);
1352 table.attach(entry[i], 1, 2, i, i + 1, Gtk::FILL | Gtk::EXPAND,
1353 Gtk::SHRINK);
1354 }
1355
1356 add(table);
1357 // add_button(Gtk::Stock::CANCEL, 0);
1358 // add_button(Gtk::Stock::OK, 1);
1359 show_all_children();
1360 }
1361
1362 void PropDialog::set_info(DLS::Info* info)
1363 {
1364 entry[0].set_text(info->Name);
1365 entry[1].set_text(info->CreationDate);
1366 entry[2].set_text(Glib::convert(info->Comments, "UTF-8", "ISO-8859-1"));
1367 entry[3].set_text(info->Product);
1368 entry[4].set_text(info->Copyright);
1369 entry[5].set_text(info->Artists);
1370 entry[6].set_text(info->Genre);
1371 entry[7].set_text(info->Keywords);
1372 entry[8].set_text(info->Engineer);
1373 entry[9].set_text(info->Technician);
1374 entry[10].set_text(info->Software);
1375 entry[11].set_text(info->Medium);
1376 entry[12].set_text(info->Source);
1377 entry[13].set_text(info->SourceForm);
1378 entry[14].set_text(info->Commissioned);
1379 entry[15].set_text(info->Subject);
1380 }
1381
1382
1383 InstrumentProps::InstrumentProps()
1384 : table(2,1),
1385 quitButton(Gtk::Stock::CLOSE)
1386 {
1387 table.set_col_spacings(5);
1388 char* propLabels[] = {
1389 "Name:",
1390 "IsDrum:",
1391 "MIDIBank:",
1392 "MIDIProgram:",
1393 "Attenuation:",
1394 "EffectSend:",
1395 "FineTune:",
1396 "PitchbendRange:",
1397 "PianoReleaseMode:",
1398 "DimensionKeyRange:",
1399 };
1400 int entryIdx = 0, checkIdx = 0;
1401 for (int i = 0 ; i < sizeof(propLabels) / sizeof(char*) ; i++) {
1402 label[i].set_text(propLabels[i]);
1403 label[i].set_alignment(Gtk::ALIGN_LEFT);
1404 table.attach(label[i], 0, 1, i, i + 1, Gtk::FILL, Gtk::SHRINK);
1405 if (i == 1 || i == 8)
1406 table.attach(check[checkIdx++], 1, 2, i, i + 1,
1407 Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
1408 else
1409 table.attach(entry[entryIdx++], 1, 2, i, i + 1,
1410 Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK);
1411 }
1412
1413 // vbox { table buttonBox { quitButton } }
1414
1415 //get_vbox()->pack_start(table);
1416 // set_border_width(6);
1417 add(vbox);
1418 table.set_border_width(2);
1419 vbox.pack_start(table);
1420 table.show();
1421 vbox.pack_start(buttonBox);
1422 buttonBox.set_layout(Gtk::BUTTONBOX_END);
1423 buttonBox.set_border_width(5);
1424 buttonBox.show();
1425 buttonBox.pack_start(quitButton);
1426 quitButton.set_flags(Gtk::CAN_DEFAULT);
1427 quitButton.grab_focus();
1428
1429 quitButton.signal_clicked().connect(
1430 sigc::mem_fun(*this, &InstrumentProps::hide));
1431
1432 // quitButton.grab_default();
1433 quitButton.show();
1434 // add(table);
1435 vbox.show();
1436 show_all_children();
1437 }
1438
1439
1440 void InstrumentProps::set_instrument(gig::Instrument* instrument)
1441 {
1442 char buf[100];
1443
1444 int entryIdx = 0, checkIdx = 0;
1445 entry[entryIdx++].set_text(instrument->pInfo->Name);
1446 check[checkIdx++].set_active(instrument->IsDrum);
1447 sprintf(buf, "%d", instrument->MIDIBank);
1448 entry[entryIdx++].set_text(buf);
1449 sprintf(buf, "%d", instrument->MIDIProgram);
1450 entry[entryIdx++].set_text(buf);
1451 sprintf(buf, "%d", instrument->Attenuation);
1452 entry[entryIdx++].set_text(buf);
1453 sprintf(buf, "%d", instrument->EffectSend);
1454 entry[entryIdx++].set_text(buf);
1455 sprintf(buf, "%d", instrument->FineTune);
1456 entry[entryIdx++].set_text(buf);
1457 sprintf(buf, "%d", instrument->PitchbendRange);
1458 entry[entryIdx++].set_text(buf);
1459 check[checkIdx++].set_active(instrument->PianoReleaseMode);
1460 sprintf(buf, "%s%d (%d)..%s%d (%d)",
1461 notes[instrument->DimensionKeyRange.low % 12],
1462 instrument->DimensionKeyRange.low / 12 - 1,
1463 instrument->DimensionKeyRange.low,
1464 notes[instrument->DimensionKeyRange.high % 12],
1465 instrument->DimensionKeyRange.high / 12 - 1,
1466 instrument->DimensionKeyRange.high);
1467 entry[entryIdx].set_text(buf);
1468 }
1469
1470 void MainWindow::getInfo(const char *filename)
1471 {
1472 RIFF::File* riff = new RIFF::File(filename);
1473 gig::File* gig = new gig::File(riff);
1474
1475 load_gig(gig, filename);
1476 }
1477
1478 void MainWindow::load_gig(gig::File* gig, const char* filename)
1479 {
1480 file = gig;
1481
1482 const char *basename = strrchr(filename, '/');
1483 basename = basename ? basename + 1 : filename;
1484
1485 set_title(basename);
1486
1487 propDialog.set_info(gig->pInfo);
1488
1489 Gtk::MenuItem* instrument_menu =
1490 dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/MenuBar/MenuInstrument"));
1491
1492 int instrument_index = 0;
1493 for (gig::Instrument* instrument = gig->GetFirstInstrument() ; instrument ;
1494 instrument = gig->GetNextInstrument()) {
1495 Gtk::TreeModel::iterator iter = m_refTreeModel->append();
1496 Gtk::TreeModel::Row row = *iter;
1497 row[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();
1498 row[m_Columns.m_col_instr] = instrument;
1499 // create a menu item for this instrument
1500 Gtk::MenuItem* item= new Gtk::MenuItem(instrument->pInfo->Name.c_str());
1501 instrument_menu->get_submenu()->append(*item);
1502 item->signal_activate().connect(
1503 sigc::bind(
1504 sigc::mem_fun(*this, &MainWindow::on_instrument_selection_change),
1505 instrument_index
1506 )
1507 );
1508 instrument_index++;
1509 }
1510 instrument_menu->show();
1511 instrument_menu->get_submenu()->show_all_children();
1512 }
1513
1514 void MainWindow::on_button_release(GdkEventButton* button)
1515 {
1516 if (button->type == GDK_2BUTTON_PRESS) {
1517 Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
1518 Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();
1519 if (it)
1520 {
1521 Gtk::TreeModel::Row row = *it;
1522 if (row[m_Columns.m_col_instr])
1523 {
1524 instrumentProps.set_instrument(row[m_Columns.m_col_instr]);
1525 instrumentProps.show();
1526 instrumentProps.deiconify();
1527 }
1528 }
1529 } else if (button->type == GDK_BUTTON_PRESS && button->button == 3) {
1530 popup_menu->popup(button->button, button->time);
1531 }
1532 }
1533
1534 void MainWindow::on_instrument_selection_change(int index) {
1535 m_RegionChooser.set_instrument(file->GetInstrument(index));
1536 }

  ViewVC Help
Powered by ViewVC