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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC