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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1087 - (show annotations) (download) (as text)
Fri Mar 9 19:45:45 2007 UTC (17 years ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 16861 byte(s)
* coarsely finished 'Sample Add' feature: works non-destructive, that is
  samples are just queued to be imported and the heavy task of resizing the
  .gig file physically and importing the sample data is done when 'Save' is
  issued (Note however: unfortunately it seems to crash yet when calling
  'Save')

1 /* -*- c++ -*-
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 #ifndef GIGEDIT_MAINWINDOW_H
21 #define GIGEDIT_MAINWINDOW_H
22
23 #include <gig.h>
24
25 #include <gtkmm/actiongroup.h>
26 #include <gtkmm/alignment.h>
27 #include <gtkmm/box.h>
28 #include <gtkmm/buttonbox.h>
29 #include <gtkmm/combobox.h>
30 #include <gtkmm/comboboxtext.h>
31 #include <gtkmm/dialog.h>
32 #include <gtkmm/entry.h>
33 #include <gtkmm/label.h>
34 #include <gtkmm/liststore.h>
35 #include <gtkmm/notebook.h>
36 #include <gtkmm/paned.h>
37 #include <gtkmm/progressbar.h>
38 #include <gtkmm/scale.h>
39 #include <gtkmm/scrolledwindow.h>
40 #include <gtkmm/spinbutton.h>
41 #include <gtkmm/table.h>
42 #include <gtkmm/treestore.h>
43 #include <gtkmm/treeview.h>
44 #include <gtkmm/uimanager.h>
45 #include <gtkmm/window.h>
46 #include <gtkmm/menuitem.h>
47
48 #include <sstream>
49
50 #include "regionchooser.h"
51 #include "dimregionchooser.h"
52
53 extern bool update_gui;
54
55 class MainWindow;
56
57 class PropDialog : public Gtk::Window {
58 public:
59 PropDialog();
60 void set_info(DLS::Info* info);
61 protected:
62 Gtk::Table table;
63 Gtk::Label label[16];
64 Gtk::Entry entry[16];
65 };
66
67 class InstrumentProps : public Gtk::Window {
68 public:
69 InstrumentProps();
70 void set_instrument(gig::Instrument* instrument);
71 protected:
72 Gtk::VBox vbox;
73 Gtk::HButtonBox buttonBox;
74 Gtk::Button quitButton;
75 Gtk::Table table;
76 Gtk::Label label[10];
77 Gtk::Entry entry[8];
78 Gtk::CheckButton check[2];
79 };
80
81 class LoadDialog : public Gtk::Dialog {
82 public:
83 LoadDialog();
84 void set_fraction(float fraction) { progressBar.set_fraction(fraction); }
85 protected:
86 Gtk::ProgressBar progressBar;
87 };
88
89 class Loader : public sigc::trackable {
90 public:
91 Loader(const char* filename);
92 void launch();
93 Glib::Dispatcher& signal_progress();
94 Glib::Dispatcher& signal_finished();
95 void progress_callback(float fraction);
96 float get_progress();
97 const char* filename;
98 gig::File* gig;
99
100 private:
101 Glib::Thread* thread;
102 void thread_function();
103 Glib::Dispatcher finished_dispatcher;
104 Glib::Dispatcher progress_dispatcher;
105 Glib::Mutex progressMutex;
106 float progress;
107 };
108
109 class LabelWidget {
110 public:
111 Gtk::Label label;
112 Gtk::Widget& widget;
113
114 LabelWidget(char* labelText, Gtk::Widget& widget);
115 void set_sensitive(bool sensitive = true);
116 };
117
118
119 template<typename T2>
120 class NumEntry : public LabelWidget {
121 protected:
122 Gtk::Adjustment adjust;
123 Gtk::HScale scale;
124 Gtk::SpinButton spinbutton;
125 Gtk::HBox box;
126 T2* dimreg;
127 public:
128 NumEntry(char* labelText, double lower = 0, double upper = 127,
129 int decimals = 0);
130 void set_value(double value) {
131 spinbutton.set_value(value);
132 }
133 Glib::SignalProxy0<void> signal_value_changed() {
134 return spinbutton.signal_value_changed();
135 }
136 double get_value() const {
137 return spinbutton.get_value();
138 }
139 };
140
141 template<typename T2>
142 NumEntry<T2>::NumEntry(char* labelText, double lower, double upper,
143 int decimals) :
144 adjust(lower, lower, upper, 1, 10),
145 scale(adjust),
146 spinbutton(adjust),
147 LabelWidget(labelText, box)
148 {
149 spinbutton.set_digits(decimals);
150 scale.set_draw_value(false);
151 box.pack_start(spinbutton, Gtk::PACK_SHRINK);
152 box.add(scale);
153 }
154
155 class NumEntryGain : public NumEntry<gig::DimensionRegion> {
156 private:
157 void value_changed();
158 public:
159 NumEntryGain(char* labelText,
160 double lower, double upper, int decimals);
161 void set_dimreg(gig::DimensionRegion* dimreg);
162 };
163
164 template<typename T>
165 class NumEntryX : public NumEntry<gig::DimensionRegion> {
166 private:
167 T& (*access)(gig::DimensionRegion*);
168 void value_changed();
169 public:
170 NumEntryX(char* labelText, T& (*access)(gig::DimensionRegion*),
171 double lower = 0, double upper = 127, int decimals = 0);
172 void set_dimreg(gig::DimensionRegion* dimreg);
173 };
174
175 template<typename T>
176 NumEntryX<T>::NumEntryX(char* labelText, T& (*access)(gig::DimensionRegion*),
177 double lower, double upper, int decimals) :
178 NumEntry<gig::DimensionRegion>(labelText, lower, upper, decimals),
179 access(access)
180 {
181 spinbutton.signal_value_changed().connect(
182 sigc::mem_fun(*this, &NumEntryX::value_changed));
183 }
184
185 template<typename T>
186 void NumEntryX<T>::value_changed()
187 {
188 if (dimreg && update_gui) {
189 access(dimreg) = T(spinbutton.get_value());
190 }
191 }
192
193 template<typename T>
194 void NumEntryX<T>::set_dimreg(gig::DimensionRegion* dimreg)
195 {
196 this->dimreg = 0;
197 set_value(access(dimreg));
198 this->dimreg = dimreg;
199 }
200
201
202 class NoteEntry : public NumEntryX<uint8_t> {
203 public:
204 NoteEntry(char* labelText, uint8_t& (*access)(gig::DimensionRegion*));
205 private:
206 int on_input(double* new_value);
207 bool on_output();
208 };
209
210
211 template<typename T, typename T2 = gig::DimensionRegion>
212 class NumEntryTemp : public NumEntry<T2> {
213 using NumEntry<T2>::spinbutton;
214 using NumEntry<T2>::dimreg;
215 private:
216 T T2::* param;
217 void value_changed();
218 public:
219 NumEntryTemp(char* labelText, T T2::* param,
220 double lower = 0, double upper = 127, int decimals = 0);
221 void set_dimreg(gig::DimensionRegion* dimreg);
222 };
223
224 template<typename T, typename T2>
225 NumEntryTemp<T, T2>::NumEntryTemp(char* labelText, T T2::* param,
226 double lower, double upper, int decimals) :
227 NumEntry<T2>(labelText, lower, upper, decimals),
228 param(param)
229 {
230 spinbutton.signal_value_changed().connect(
231 sigc::mem_fun(*this, &NumEntryTemp<T, T2>::value_changed));
232 }
233
234 template<typename T, typename T2>
235 void NumEntryTemp<T, T2>::value_changed()
236 {
237 if (dimreg && update_gui) {
238 dimreg->*param = T(spinbutton.get_value());
239 }
240 }
241
242 template<typename T, typename T2>
243 void NumEntryTemp<T, T2>::set_dimreg(gig::DimensionRegion* dimreg)
244 {
245 this->dimreg = 0;
246 set_value(dimreg->*param);
247 this->dimreg = dimreg;
248 }
249
250
251
252 class NumEntryPermille : public NumEntry<gig::DimensionRegion> {
253 private:
254 uint16_t gig::DimensionRegion::* param;
255 void value_changed();
256 public:
257 NumEntryPermille(char* labelText, uint16_t gig::DimensionRegion::* param,
258 double lower = 0, double upper = 127, int decimals = 0);
259 void set_dimreg(gig::DimensionRegion* dimreg);
260 };
261
262
263 template<typename T>
264 class ChoiceEntry : public LabelWidget {
265 private:
266 Gtk::ComboBoxText combobox;
267 Gtk::Alignment align;
268 T gig::DimensionRegion::* param;
269 gig::DimensionRegion* dimreg;
270 void value_changed();
271 const T* values;
272 public:
273 ChoiceEntry(char* labelText,
274 T gig::DimensionRegion::* param);
275 void set_choices(char** texts, const T* values);
276 void set_dimreg(gig::DimensionRegion* dimreg);
277 int get_active_row_number() { return combobox.get_active_row_number(); }
278 Glib::SignalProxy0<void> signal_changed() {
279 return combobox.signal_changed();
280 }
281 };
282
283 template<typename T>
284 ChoiceEntry<T>::ChoiceEntry(char* labelText,
285 T gig::DimensionRegion::* param) :
286 align(0, 0, 0, 0),
287 LabelWidget(labelText, align),
288 param(param)
289 {
290 combobox.signal_changed().connect(
291 sigc::mem_fun(*this, &ChoiceEntry::value_changed));
292 align.add(combobox);
293 }
294
295 template<typename T>
296 void ChoiceEntry<T>::set_choices(char** texts, const T* values)
297 {
298 for (int i = 0 ; texts[i] ; i++) {
299 combobox.append_text(texts[i]);
300 }
301 this->values = values;
302 }
303
304 template<typename T>
305 void ChoiceEntry<T>::value_changed()
306 {
307 if (dimreg && update_gui) {
308 int rowno = combobox.get_active_row_number();
309 if (rowno != -1) dimreg->*param = values[rowno];
310 }
311 }
312
313 template<typename T>
314 void ChoiceEntry<T>::set_dimreg(gig::DimensionRegion* dimreg)
315 {
316 this->dimreg = 0;
317 T value = dimreg->*param;
318 int row = 0;
319 int nb_rows = combobox.get_model()->children().size();
320 for (; row < nb_rows ; row++) {
321 if (value == values[row]) break;
322 }
323 combobox.set_active(row == nb_rows ? -1 : row);
324 this->dimreg = dimreg;
325 }
326
327
328 class ChoiceEntryLeverageCtrl : public LabelWidget {
329 private:
330 Gtk::ComboBoxText combobox;
331 Gtk::Alignment align;
332 gig::leverage_ctrl_t gig::DimensionRegion::* param;
333 gig::DimensionRegion* dimreg;
334 void value_changed();
335 public:
336 ChoiceEntryLeverageCtrl(char* labelText,
337 gig::leverage_ctrl_t gig::DimensionRegion::* param);
338 void set_dimreg(gig::DimensionRegion* dimreg);
339 int get_active_row_number() { return combobox.get_active_row_number(); }
340 Glib::SignalProxy0<void> signal_changed() {
341 return combobox.signal_changed();
342 }
343 };
344
345
346
347 class BoolEntry : public LabelWidget {
348 private:
349 Gtk::CheckButton checkbutton;
350 bool gig::DimensionRegion::* param;
351 gig::DimensionRegion* dimreg;
352 void value_changed();
353 public:
354 BoolEntry(char* labelText, bool gig::DimensionRegion::* param);
355 void set_dimreg(gig::DimensionRegion* dimreg);
356 bool get_active() { return checkbutton.get_active(); }
357 Glib::SignalProxy0<void> signal_toggled() {
358 return checkbutton.signal_toggled();
359 }
360 };
361
362 class MainWindow : public Gtk::Window {
363 public:
364 MainWindow();
365 virtual ~MainWindow();
366 void getInfo(const char* filename);
367
368 protected:
369 Glib::RefPtr<Gtk::ActionGroup> actionGroup;
370 Glib::RefPtr<Gtk::UIManager> uiManager;
371
372 int rowno;
373 int pageno;
374 int firstRowInBlock;
375
376 NumEntryTemp<uint8_t> eVelocityUpperLimit;
377 NumEntryPermille eEG1PreAttack;
378 NumEntryTemp<double> eEG1Attack;
379 NumEntryTemp<double> eEG1Decay1;
380 NumEntryTemp<double> eEG1Decay2;
381 BoolEntry eEG1InfiniteSustain;
382 NumEntryPermille eEG1Sustain;
383 NumEntryTemp<double> eEG1Release;
384 BoolEntry eEG1Hold;
385 ChoiceEntryLeverageCtrl eEG1Controller;
386 BoolEntry eEG1ControllerInvert;
387 NumEntryTemp<uint8_t> eEG1ControllerAttackInfluence;
388 NumEntryTemp<uint8_t> eEG1ControllerDecayInfluence;
389 NumEntryTemp<uint8_t> eEG1ControllerReleaseInfluence;
390 NumEntryTemp<double> eLFO1Frequency;
391 NumEntryTemp<uint16_t> eLFO1InternalDepth;
392 NumEntryTemp<uint16_t> eLFO1ControlDepth;
393 ChoiceEntry<gig::lfo1_ctrl_t> eLFO1Controller;
394 BoolEntry eLFO1FlipPhase;
395 BoolEntry eLFO1Sync;
396 NumEntryPermille eEG2PreAttack;
397 NumEntryTemp<double> eEG2Attack;
398 NumEntryTemp<double> eEG2Decay1;
399 NumEntryTemp<double> eEG2Decay2;
400 BoolEntry eEG2InfiniteSustain;
401 NumEntryPermille eEG2Sustain;
402 NumEntryTemp<double> eEG2Release;
403 ChoiceEntryLeverageCtrl eEG2Controller;
404 BoolEntry eEG2ControllerInvert;
405 NumEntryTemp<uint8_t> eEG2ControllerAttackInfluence;
406 NumEntryTemp<uint8_t> eEG2ControllerDecayInfluence;
407 NumEntryTemp<uint8_t> eEG2ControllerReleaseInfluence;
408 NumEntryTemp<double> eLFO2Frequency;
409 NumEntryTemp<uint16_t> eLFO2InternalDepth;
410 NumEntryTemp<uint16_t> eLFO2ControlDepth;
411 ChoiceEntry<gig::lfo2_ctrl_t> eLFO2Controller;
412 BoolEntry eLFO2FlipPhase;
413 BoolEntry eLFO2Sync;
414 NumEntryTemp<double> eEG3Attack;
415 NumEntryTemp<int16_t> eEG3Depth;
416 NumEntryTemp<double> eLFO3Frequency;
417 NumEntryTemp<int16_t> eLFO3InternalDepth;
418 NumEntryTemp<int16_t> eLFO3ControlDepth;
419 ChoiceEntry<gig::lfo3_ctrl_t> eLFO3Controller;
420 BoolEntry eLFO3Sync;
421 BoolEntry eVCFEnabled;
422 ChoiceEntry<gig::vcf_type_t> eVCFType;
423 ChoiceEntry<gig::vcf_cutoff_ctrl_t> eVCFCutoffController;
424 BoolEntry eVCFCutoffControllerInvert;
425 NumEntryTemp<uint8_t> eVCFCutoff;
426 ChoiceEntry<gig::curve_type_t> eVCFVelocityCurve;
427 NumEntryTemp<uint8_t> eVCFVelocityScale;
428 NumEntryTemp<uint8_t> eVCFVelocityDynamicRange;
429 NumEntryTemp<uint8_t> eVCFResonance;
430 BoolEntry eVCFResonanceDynamic;
431 ChoiceEntry<gig::vcf_res_ctrl_t> eVCFResonanceController;
432 BoolEntry eVCFKeyboardTracking;
433 NumEntryTemp<uint8_t> eVCFKeyboardTrackingBreakpoint;
434 ChoiceEntry<gig::curve_type_t> eVelocityResponseCurve;
435 NumEntryTemp<uint8_t> eVelocityResponseDepth;
436 NumEntryTemp<uint8_t> eVelocityResponseCurveScaling;
437 ChoiceEntry<gig::curve_type_t> eReleaseVelocityResponseCurve;
438 NumEntryTemp<uint8_t> eReleaseVelocityResponseDepth;
439 NumEntryTemp<uint8_t> eReleaseTriggerDecay;
440 NumEntryX<uint8_t> eCrossfade_in_start;
441 NumEntryX<uint8_t> eCrossfade_in_end;
442 NumEntryX<uint8_t> eCrossfade_out_start;
443 NumEntryX<uint8_t> eCrossfade_out_end;
444 BoolEntry ePitchTrack;
445 ChoiceEntry<gig::dim_bypass_ctrl_t> eDimensionBypass;
446 NumEntryTemp<int8_t> ePan;
447 BoolEntry eSelfMask;
448 ChoiceEntryLeverageCtrl eAttenuationController;
449 BoolEntry eInvertAttenuationController;
450 NumEntryTemp<uint8_t> eAttenuationControllerThreshold;
451 NumEntryTemp<uint8_t> eChannelOffset;
452 BoolEntry eSustainDefeat;
453 BoolEntry eMSDecode;
454 NumEntryTemp<uint16_t> eSampleStartOffset;
455 // NumEntryX<uint8_t> eUnityNote;
456 NoteEntry eUnityNote;
457 NumEntryX<int16_t> eFineTune;
458 NumEntryGain eGain;
459 NumEntryX<uint32_t> eSampleLoops;
460
461 void addProp(LabelWidget& labelwidget);
462 void addString(char* labelText, Gtk::Label*& label,
463 Gtk::Entry*& widget);
464 void addHeader(char* text);
465 void nextPage();
466
467 RegionChooser m_RegionChooser;
468 DimRegionChooser m_DimRegionChooser;
469
470 void set_dim_region(gig::DimensionRegion* d);
471 PropDialog propDialog;
472 InstrumentProps instrumentProps;
473
474 void on_instrument_selection_change(int index);
475 void on_sel_change();
476 void region_changed();
477 void dimreg_changed();
478 void on_loader_progress();
479 void on_loader_finished();
480
481 class ModelColumns : public Gtk::TreeModel::ColumnRecord {
482 public:
483
484 ModelColumns() {
485 add(m_col_name);
486 add(m_col_instr);
487 }
488
489 Gtk::TreeModelColumn<Glib::ustring> m_col_name;
490 Gtk::TreeModelColumn<gig::Instrument*> m_col_instr;
491 } m_Columns;
492
493 Gtk::VBox m_VBox;
494 Gtk::HPaned m_HPaned;
495
496 Gtk::ScrolledWindow m_ScrolledWindow;
497 Gtk::TreeView m_TreeView;
498 Glib::RefPtr<Gtk::ListStore> m_refTreeModel;
499
500 class SamplesModel : public Gtk::TreeModel::ColumnRecord {
501 public:
502 SamplesModel() {
503 add(m_col_name);
504 add(m_col_sample);
505 add(m_col_group);
506 }
507
508 Gtk::TreeModelColumn<Glib::ustring> m_col_name;
509 Gtk::TreeModelColumn<gig::Sample*> m_col_sample;
510 Gtk::TreeModelColumn<gig::Group*> m_col_group;
511 } m_SamplesModel;
512 Gtk::TreeView m_TreeViewSamples;
513 Glib::RefPtr<Gtk::TreeStore> m_refSamplesTreeModel;
514
515 Gtk::Notebook m_Notebook;
516 Gtk::Notebook m_TreeViewNotebook;
517
518 Gtk::Table* table[5];
519
520 // dimensionregion parameter widgets
521 // TODO: remove:
522 Gtk::Label* lSample;
523 Gtk::Entry* wSample;
524
525 struct SampleImportItem {
526 gig::Sample* gig_sample; // pointer to the gig::Sample to which the sample data should be imported to
527 Glib::ustring sample_path; // file name of the sample to be imported
528 };
529 std::list<SampleImportItem> m_SampleImportQueue;
530
531 void VCFEnabled_toggled();
532 void VCFCutoffController_changed();
533 void VCFResonanceController_changed();
534 void EG1InfiniteSustain_toggled();
535 void EG2InfiniteSustain_toggled();
536 void EG1Controller_changed();
537 void EG2Controller_changed();
538 void AttenuationController_changed();
539 void LFO1Controller_changed();
540 void LFO2Controller_changed();
541 void LFO3Controller_changed();
542 void crossfade1_changed();
543 void crossfade2_changed();
544 void crossfade3_changed();
545 void crossfade4_changed();
546
547 void on_action_file_new();
548 void on_action_file_open();
549 void on_action_file_save();
550 void on_action_file_save_as();
551 void on_action_file_properties();
552 void on_action_help_about();
553
554 // sample right-click popup actions
555 void on_sample_treeview_button_release(GdkEventButton* button);
556 void on_action_sample_properties();
557 void on_action_add_group();
558 void on_action_add_sample();
559 void on_action_remove_sample();
560
561 LoadDialog* load_dialog;
562 Loader* loader;
563 void load_gig(gig::File* gig, const char* filename);
564
565 gig::File* file;
566
567 void on_button_release(GdkEventButton* button);
568
569 void __import_queued_samples();
570
571 Gtk::Menu* popup_menu;
572 };
573
574 #endif

  ViewVC Help
Powered by ViewVC