/[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 2169 - (hide annotations) (download)
Sun Mar 6 07:51:04 2011 UTC (13 years ago) by persson
File size: 15217 byte(s)
* ported to gtkmm 3, keeping compatibility with gtkmm 2

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

  ViewVC Help
Powered by ViewVC