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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1075 - (hide annotations) (download)
Tue Mar 6 01:17:03 2007 UTC (17 years ago) by schoenebeck
File size: 53129 byte(s)
* instrument menu items are now mutual exclusive radio menu items

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     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 schoenebeck 1069 actionGroup->add(Gtk::Action::create("MenuInstrument", _("_Instrument")));
820    
821 persson 1052 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 schoenebeck 1069 " <menu action='MenuInstrument'>"
853     " </menu>"
854 persson 1052 #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 schoenebeck 1069 // 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 persson 1052 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 schoenebeck 1069 Gtk::MenuItem* instrument_menu =
1490     dynamic_cast<Gtk::MenuItem*>(uiManager->get_widget("/MenuBar/MenuInstrument"));
1491    
1492     int instrument_index = 0;
1493 schoenebeck 1075 Gtk::RadioMenuItem::Group instrument_group;
1494 persson 1052 for (gig::Instrument* instrument = gig->GetFirstInstrument() ; instrument ;
1495     instrument = gig->GetNextInstrument()) {
1496     Gtk::TreeModel::iterator iter = m_refTreeModel->append();
1497     Gtk::TreeModel::Row row = *iter;
1498     row[m_Columns.m_col_name] = instrument->pInfo->Name.c_str();
1499     row[m_Columns.m_col_instr] = instrument;
1500 schoenebeck 1069 // create a menu item for this instrument
1501 schoenebeck 1075 Gtk::RadioMenuItem* item= new Gtk::RadioMenuItem(instrument_group, instrument->pInfo->Name.c_str());
1502 schoenebeck 1069 instrument_menu->get_submenu()->append(*item);
1503     item->signal_activate().connect(
1504     sigc::bind(
1505     sigc::mem_fun(*this, &MainWindow::on_instrument_selection_change),
1506     instrument_index
1507     )
1508     );
1509     instrument_index++;
1510 persson 1052 }
1511 schoenebeck 1069 instrument_menu->show();
1512     instrument_menu->get_submenu()->show_all_children();
1513 persson 1052 }
1514    
1515     void MainWindow::on_button_release(GdkEventButton* button)
1516     {
1517     if (button->type == GDK_2BUTTON_PRESS) {
1518     Glib::RefPtr<Gtk::TreeSelection> tree_sel_ref = m_TreeView.get_selection();
1519     Gtk::TreeModel::iterator it = tree_sel_ref->get_selected();
1520     if (it)
1521     {
1522     Gtk::TreeModel::Row row = *it;
1523     if (row[m_Columns.m_col_instr])
1524     {
1525     instrumentProps.set_instrument(row[m_Columns.m_col_instr]);
1526     instrumentProps.show();
1527     instrumentProps.deiconify();
1528     }
1529     }
1530     } else if (button->type == GDK_BUTTON_PRESS && button->button == 3) {
1531     popup_menu->popup(button->button, button->time);
1532     }
1533     }
1534 schoenebeck 1069
1535     void MainWindow::on_instrument_selection_change(int index) {
1536     m_RegionChooser.set_instrument(file->GetInstrument(index));
1537     }

  ViewVC Help
Powered by ViewVC