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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1831 - (hide annotations) (download)
Tue Feb 3 19:38:19 2009 UTC (15 years, 1 month ago) by persson
File size: 15124 byte(s)
* made all visible strings translatable

1 schoenebeck 1225 /* -*- c++ -*-
2 persson 1831 * Copyright (C) 2006-2009 Andreas Persson
3 schoenebeck 1225 *
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 "dimensionmanager.h"
21    
22     #include <gtkmm/stock.h>
23     #include <gtkmm/messagedialog.h>
24     #include <gtkmm/dialog.h>
25     #include <gtkmm/comboboxtext.h>
26 persson 1733 #include <gtkmm/spinbutton.h>
27     #include <gtkmm/table.h>
28 schoenebeck 1225
29 persson 1831 #include "global.h"
30    
31 schoenebeck 1225 // returns a human readable name of the given dimension type
32     static Glib::ustring __dimTypeAsString(gig::dimension_t d) {
33     char buf[32];
34     switch (d) {
35     case gig::dimension_none:
36 persson 1831 return _("None");
37 schoenebeck 1225 case gig::dimension_samplechannel:
38 persson 1831 return _("Sample Channel");
39 schoenebeck 1225 case gig::dimension_layer:
40 persson 1831 return _("Layer");
41 schoenebeck 1225 case gig::dimension_velocity:
42 persson 1831 return _("Velocity");
43 schoenebeck 1225 case gig::dimension_channelaftertouch:
44 persson 1831 return _("Aftertouch");
45 schoenebeck 1225 case gig::dimension_releasetrigger:
46 persson 1831 return _("Release Trigger");
47 schoenebeck 1225 case gig::dimension_keyboard:
48 persson 1831 return _("Keyswitching");
49 schoenebeck 1225 case gig::dimension_roundrobin:
50 persson 1831 return _("Round Robin");
51 schoenebeck 1225 case gig::dimension_random:
52 persson 1831 return _("Random Generator");
53 schoenebeck 1225 case gig::dimension_smartmidi:
54 persson 1831 return _("Smart MIDI");
55 schoenebeck 1225 case gig::dimension_roundrobinkeyboard:
56 persson 1831 return _("Keyboard Round Robin");
57 schoenebeck 1225 case gig::dimension_modwheel:
58 persson 1831 return _("Modulation Wheel");
59 schoenebeck 1225 case gig::dimension_breath:
60 persson 1831 return _("Breath Ctrl.");
61 schoenebeck 1225 case gig::dimension_foot:
62 persson 1831 return _("Foot Ctrl.");
63 schoenebeck 1225 case gig::dimension_portamentotime:
64 persson 1831 return _("Portamento Time Ctrl.");
65 schoenebeck 1225 case gig::dimension_effect1:
66 persson 1831 return _("Effect Ctrl. 1");
67 schoenebeck 1225 case gig::dimension_effect2:
68 persson 1831 return _("Effect Ctrl. 2");
69 schoenebeck 1225 case gig::dimension_genpurpose1:
70 persson 1831 return _("General Purpose Ctrl. 1");
71 schoenebeck 1225 case gig::dimension_genpurpose2:
72 persson 1831 return _("General Purpose Ctrl. 2");
73 schoenebeck 1225 case gig::dimension_genpurpose3:
74 persson 1831 return _("General Purpose Ctrl. 3");
75 schoenebeck 1225 case gig::dimension_genpurpose4:
76 persson 1831 return _("General Purpose Ctrl. 4");
77 schoenebeck 1225 case gig::dimension_sustainpedal:
78 persson 1831 return _("Sustain Pedal");
79 schoenebeck 1225 case gig::dimension_portamento:
80 persson 1831 return _("Portamento Ctrl.");
81 schoenebeck 1225 case gig::dimension_sostenutopedal:
82 persson 1831 return _("Sostenuto Pedal");
83 schoenebeck 1225 case gig::dimension_softpedal:
84 persson 1831 return _("Soft Pedal");
85 schoenebeck 1225 case gig::dimension_genpurpose5:
86 persson 1831 return _("General Purpose Ctrl. 5");
87 schoenebeck 1225 case gig::dimension_genpurpose6:
88 persson 1831 return _("General Purpose Ctrl. 6");
89 schoenebeck 1225 case gig::dimension_genpurpose7:
90 persson 1831 return _("General Purpose Ctrl. 7");
91 schoenebeck 1225 case gig::dimension_genpurpose8:
92 persson 1831 return _("General Purpose Ctrl. 8");
93 schoenebeck 1225 case gig::dimension_effect1depth:
94 persson 1831 return _("Effect 1 Depth");
95 schoenebeck 1225 case gig::dimension_effect2depth:
96 persson 1831 return _("Effect 2 Depth");
97 schoenebeck 1225 case gig::dimension_effect3depth:
98 persson 1831 return _("Effect 3 Depth");
99 schoenebeck 1225 case gig::dimension_effect4depth:
100 persson 1831 return _("Effect 4 Depth");
101 schoenebeck 1225 case gig::dimension_effect5depth:
102 persson 1831 return _("Effect 5 Depth");
103 schoenebeck 1225 default:
104     sprintf(buf, "Unknown Type (0x%x) !!!", d);
105     return buf;
106     }
107     }
108    
109     // returns a human readable description of the given dimension
110     static Glib::ustring __dimDescriptionAsString(gig::dimension_t d) {
111     switch (d) {
112     case gig::dimension_none:
113 persson 1831 return _("Dimension not in use");
114 schoenebeck 1225 case gig::dimension_samplechannel:
115 persson 1831 return _("If used sample has more than one channel (thus is not mono)");
116 schoenebeck 1225 case gig::dimension_layer:
117 persson 1831 return _("For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers");
118 schoenebeck 1225 case gig::dimension_velocity:
119 persson 1831 return _("Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined)");
120 schoenebeck 1225 case gig::dimension_channelaftertouch:
121 persson 1831 return _("Channel Key Pressure");
122 schoenebeck 1225 case gig::dimension_releasetrigger:
123 persson 1831 return _("Special dimension for triggering samples on releasing a key");
124 schoenebeck 1225 case gig::dimension_keyboard:
125 persson 1831 return _("Dimension for keyswitching (keyboard)");
126 schoenebeck 1225 case gig::dimension_roundrobin:
127 persson 1831 return _("Different samples triggered each time a note is played, dimension regions selected in sequence");
128 schoenebeck 1225 case gig::dimension_random:
129 persson 1831 return _("Different samples triggered each time a note is played, random order");
130 schoenebeck 1225 case gig::dimension_smartmidi:
131 persson 1831 return _("For MIDI tools like legato and repetition mode");
132 schoenebeck 1225 case gig::dimension_roundrobinkeyboard:
133 persson 1831 return _("Different samples triggered each time a note is played, any key advances the counter");
134 schoenebeck 1225 case gig::dimension_modwheel:
135 persson 1831 return _("MIDI Controller 1");
136 schoenebeck 1225 case gig::dimension_breath:
137 persson 1831 return _("MIDI Controller 2");
138 schoenebeck 1225 case gig::dimension_foot:
139 persson 1831 return _("MIDI Controller 4");
140 schoenebeck 1225 case gig::dimension_portamentotime:
141 persson 1831 return _("MIDI Controller 5");
142 schoenebeck 1225 case gig::dimension_effect1:
143 persson 1831 return _("MIDI Controller 12");
144 schoenebeck 1225 case gig::dimension_effect2:
145 persson 1831 return _("MIDI Controller 13");
146 schoenebeck 1225 case gig::dimension_genpurpose1:
147 persson 1831 return _("Slider, MIDI Controller 16");
148 schoenebeck 1225 case gig::dimension_genpurpose2:
149 persson 1831 return _("Slider, MIDI Controller 17");
150 schoenebeck 1225 case gig::dimension_genpurpose3:
151 persson 1831 return _("Slider, MIDI Controller 18");
152 schoenebeck 1225 case gig::dimension_genpurpose4:
153 persson 1831 return _("Slider, MIDI Controller 19");
154 schoenebeck 1225 case gig::dimension_sustainpedal:
155 persson 1831 return _("MIDI Controller 64");
156 schoenebeck 1225 case gig::dimension_portamento:
157 persson 1831 return _("MIDI Controller 65");
158 schoenebeck 1225 case gig::dimension_sostenutopedal:
159 persson 1831 return _("MIDI Controller 66");
160 schoenebeck 1225 case gig::dimension_softpedal:
161 persson 1831 return _("MIDI Controller 67");
162 schoenebeck 1225 case gig::dimension_genpurpose5:
163 persson 1831 return _("Button, MIDI Controller 80");
164 schoenebeck 1225 case gig::dimension_genpurpose6:
165 persson 1831 return _("Button, MIDI Controller 81");
166 schoenebeck 1225 case gig::dimension_genpurpose7:
167 persson 1831 return _("Button, MIDI Controller 82");
168 schoenebeck 1225 case gig::dimension_genpurpose8:
169 persson 1831 return _("Button, MIDI Controller 83");
170 schoenebeck 1225 case gig::dimension_effect1depth:
171 persson 1831 return _("MIDI Controller 91");
172 schoenebeck 1225 case gig::dimension_effect2depth:
173 persson 1831 return _("MIDI Controller 92");
174 schoenebeck 1225 case gig::dimension_effect3depth:
175 persson 1831 return _("MIDI Controller 93");
176 schoenebeck 1225 case gig::dimension_effect4depth:
177 persson 1831 return _("MIDI Controller 94");
178 schoenebeck 1225 case gig::dimension_effect5depth:
179 persson 1831 return _("MIDI Controller 95");
180 schoenebeck 1225 default:
181 persson 1831 return _("Please report this !!!");
182 schoenebeck 1225 }
183     }
184    
185     DimensionManager::DimensionManager() :
186     addButton(Gtk::Stock::ADD), removeButton(Gtk::Stock::REMOVE)
187     {
188 persson 1831 set_title(_("Dimensions of selected Region"));
189 schoenebeck 1225 add(vbox);
190     scrolledWindow.add(treeView);
191     vbox.pack_start(scrolledWindow);
192     scrolledWindow.show();
193 schoenebeck 1411 vbox.pack_start(buttonBox, Gtk::PACK_SHRINK);
194 schoenebeck 1225 buttonBox.set_layout(Gtk::BUTTONBOX_END);
195     buttonBox.set_border_width(5);
196     buttonBox.show();
197 schoenebeck 1411 buttonBox.pack_start(addButton, Gtk::PACK_SHRINK);
198     buttonBox.pack_start(removeButton, Gtk::PACK_SHRINK);
199 schoenebeck 1225 addButton.show();
200     removeButton.show();
201    
202     // setup the table
203     refTableModel = Gtk::ListStore::create(tableModel);
204     treeView.set_model(refTableModel);
205 persson 1831 treeView.append_column(_("Dimension Type"), tableModel.m_dim_type);
206     treeView.append_column(_("Bits"), tableModel.m_bits);
207     treeView.append_column(_("Zones"), tableModel.m_zones);
208     treeView.append_column(_("Description"), tableModel.m_description);
209 schoenebeck 1225 treeView.show();
210    
211     addButton.signal_clicked().connect(
212     sigc::mem_fun(*this, &DimensionManager::addDimension)
213     );
214    
215     removeButton.signal_clicked().connect(
216     sigc::mem_fun(*this, &DimensionManager::removeDimension)
217     );
218    
219     show_all_children();
220     }
221    
222     // update all GUI elements according to current gig::Region informations
223     void DimensionManager::refreshManager() {
224     refTableModel->clear();
225 persson 1677 if (region) {
226     for (int i = 0; i < region->Dimensions; i++) {
227     gig::dimension_def_t* dim = &region->pDimensionDefinitions[i];
228     Gtk::TreeModel::Row row = *(refTableModel->append());
229     row[tableModel.m_dim_type] = __dimTypeAsString(dim->dimension);
230     row[tableModel.m_bits] = dim->bits;
231 persson 1733 row[tableModel.m_zones] = dim->zones;
232 persson 1677 row[tableModel.m_description] = __dimDescriptionAsString(dim->dimension);
233     row[tableModel.m_definition] = dim;
234     }
235 schoenebeck 1225 }
236 persson 1677 set_sensitive(region);
237 schoenebeck 1225 }
238    
239     void DimensionManager::show(gig::Region* region) {
240     this->region = region;
241     refreshManager();
242     Gtk::Window::show();
243     deiconify();
244     }
245    
246 persson 1677 void DimensionManager::set_region(gig::Region* region) {
247     this->region = region;
248     refreshManager();
249     }
250    
251 schoenebeck 1225 void DimensionManager::addDimension() {
252     try {
253 persson 1831 Gtk::Dialog dialog(_("New Dimension"), true /*modal*/);
254 schoenebeck 1225 // add dimension type combo box to the dialog
255     Glib::RefPtr<Gtk::ListStore> refComboModel = Gtk::ListStore::create(comboModel);
256     for (int i = 0x01; i < 0xff; i++) {
257     Glib::ustring sType =
258     __dimTypeAsString(static_cast<gig::dimension_t>(i));
259     if (sType.find("Unknown") != 0) {
260     Gtk::TreeModel::Row row = *(refComboModel->append());
261     row[comboModel.m_type_id] = i;
262     row[comboModel.m_type_name] = sType;
263     }
264     }
265 persson 1733 Gtk::Table table(2, 2);
266 persson 1831 Gtk::Label labelDimType(_("Dimension:"), Gtk::ALIGN_LEFT);
267 schoenebeck 1225 Gtk::ComboBox comboDimType;
268     comboDimType.set_model(refComboModel);
269     comboDimType.pack_start(comboModel.m_type_id);
270     comboDimType.pack_start(comboModel.m_type_name);
271 persson 1831 Gtk::Label labelZones(_("Zones:"), Gtk::ALIGN_LEFT);
272 persson 1733 table.attach(labelDimType, 0, 1, 0, 1);
273     table.attach(comboDimType, 1, 2, 0, 1);
274     table.attach(labelZones, 0, 1, 1, 2);
275     dialog.get_vbox()->pack_start(table);
276    
277     // number of zones: use a combo box with fix values for gig
278     // v2 and a spin button for v3
279 schoenebeck 1225 Gtk::ComboBoxText comboZones;
280 persson 1733 Gtk::SpinButton spinZones;
281     bool version2 = false;
282     if (region) {
283     gig::File* file = (gig::File*)region->GetParent()->GetParent();
284     version2 = file->pVersion && file->pVersion->major == 2;
285 schoenebeck 1225 }
286 persson 1733 if (version2) {
287     for (int i = 1; i <= 5; i++) {
288     char buf[3];
289     sprintf(buf, "%d", 1 << i);
290     comboZones.append_text(buf);
291     }
292     table.attach(comboZones, 1, 2, 1, 2);
293     } else {
294     spinZones.set_increments(1, 8);
295     spinZones.set_numeric(true);
296     spinZones.set_range(2, 128);
297     spinZones.set_value(2);
298     table.attach(spinZones, 1, 2, 1, 2);
299     }
300    
301 schoenebeck 1225 dialog.add_button(Gtk::Stock::OK, 0);
302     dialog.add_button(Gtk::Stock::CANCEL, 1);
303     dialog.show_all_children();
304 persson 1733
305 schoenebeck 1225 if (!dialog.run()) { // OK selected ...
306     Gtk::TreeModel::iterator iterType = comboDimType.get_active();
307     if (!iterType) return;
308     Gtk::TreeModel::Row rowType = *iterType;
309     if (!rowType) return;
310     gig::dimension_def_t dim;
311     int iTypeID = rowType[comboModel.m_type_id];
312     dim.dimension = static_cast<gig::dimension_t>(iTypeID);
313 persson 1733
314     if (version2) {
315     if (comboZones.get_active_row_number() < 0) return;
316     dim.bits = comboZones.get_active_row_number() + 1;
317     dim.zones = 1 << dim.bits;
318     } else {
319     dim.zones = spinZones.get_value_as_int();
320     // Find the number of bits required to hold the
321     // specified amount of zones.
322     int zoneBits = dim.zones - 1;
323     for (dim.bits = 0; zoneBits > 1; dim.bits += 2, zoneBits >>= 2);
324     dim.bits += zoneBits;
325     }
326 schoenebeck 1225 printf(
327     "Adding dimension (type=0x%x, bits=%d, zones=%d)\n",
328     dim.dimension, dim.bits, dim.zones
329     );
330 schoenebeck 1322 // notify everybody that we're going to update the region
331     region_to_be_changed_signal.emit(region);
332 schoenebeck 1225 // add the new dimension to the region
333     // (implicitly creates new dimension regions)
334     region->AddDimension(&dim);
335     // let everybody know there was a change
336 schoenebeck 1322 region_changed_signal.emit(region);
337 schoenebeck 1225 // update all GUI elements
338     refreshManager();
339     }
340     } catch (RIFF::Exception e) {
341 schoenebeck 1322 // notify that the changes are over (i.e. to avoid dead locks)
342     region_changed_signal.emit(region);
343     // show error message
344 persson 1831 Glib::ustring txt = _("Could not add dimension: ") + e.Message;
345 schoenebeck 1225 Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
346     msg.run();
347     }
348     }
349    
350     void DimensionManager::removeDimension() {
351     Glib::RefPtr<Gtk::TreeSelection> sel = treeView.get_selection();
352     Gtk::TreeModel::iterator it = sel->get_selected();
353     if (it) {
354     try {
355 schoenebeck 1322 // notify everybody that we're going to update the region
356     region_to_be_changed_signal.emit(region);
357 schoenebeck 1225 // remove selected dimension
358     Gtk::TreeModel::Row row = *it;
359     gig::dimension_def_t* dim = row[tableModel.m_definition];
360     region->DeleteDimension(dim);
361     // let everybody know there was a change
362 schoenebeck 1322 region_changed_signal.emit(region);
363 persson 1623 // update all GUI elements
364     refreshManager();
365 schoenebeck 1225 } catch (RIFF::Exception e) {
366 schoenebeck 1322 // notify that the changes are over (i.e. to avoid dead locks)
367     region_changed_signal.emit(region);
368     // show error message
369 persson 1831 Glib::ustring txt = _("Could not remove dimension: ") + e.Message;
370 schoenebeck 1225 Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
371     msg.run();
372     }
373     }
374     }

  ViewVC Help
Powered by ViewVC