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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1082 - (show annotations) (download)
Thu Mar 8 01:43:18 2007 UTC (17 years, 1 month ago) by schoenebeck
File size: 58039 byte(s)
* added right-click popup for sample list view
  (only item "Add Group" implemented yet)

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

  ViewVC Help
Powered by ViewVC