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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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

  ViewVC Help
Powered by ViewVC