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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1303 - (show annotations) (download)
Sun Aug 26 09:29:52 2007 UTC (16 years, 7 months ago) by persson
File size: 13068 byte(s)
* make sure samplechannel dimension gets created for stereo samples
* allow building with older versions of gtk and libsndfile
* remember selected dimension when switching regions
* fix for loop parameters for unmapped dimregions
* check if file is savable before trying to 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 #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
27 // returns a human readable name of the given dimension type
28 static Glib::ustring __dimTypeAsString(gig::dimension_t d) {
29 char buf[32];
30 switch (d) {
31 case gig::dimension_none:
32 return "None";
33 case gig::dimension_samplechannel:
34 return "Sample Channel";
35 case gig::dimension_layer:
36 return "Layer";
37 case gig::dimension_velocity:
38 return "Velocity";
39 case gig::dimension_channelaftertouch:
40 return "Aftertouch";
41 case gig::dimension_releasetrigger:
42 return "Release Trigger";
43 case gig::dimension_keyboard:
44 return "Keyswitching";
45 case gig::dimension_roundrobin:
46 return "Round Robin";
47 case gig::dimension_random:
48 return "Random Generator";
49 case gig::dimension_smartmidi:
50 return "Smart MIDI";
51 case gig::dimension_roundrobinkeyboard:
52 return "Keyboard Round Robin";
53 case gig::dimension_modwheel:
54 return "Modulation Wheel";
55 case gig::dimension_breath:
56 return "Breath Ctrl.";
57 case gig::dimension_foot:
58 return "Foot Ctrl.";
59 case gig::dimension_portamentotime:
60 return "Portamento Time Ctrl.";
61 case gig::dimension_effect1:
62 return "Effect Ctrl. 1";
63 case gig::dimension_effect2:
64 return "Effect Ctrl. 2";
65 case gig::dimension_genpurpose1:
66 return "General Purpose Ctrl. 1";
67 case gig::dimension_genpurpose2:
68 return "General Purpose Ctrl. 2";
69 case gig::dimension_genpurpose3:
70 return "General Purpose Ctrl. 3";
71 case gig::dimension_genpurpose4:
72 return "General Purpose Ctrl. 4";
73 case gig::dimension_sustainpedal:
74 return "Sustain Pedal";
75 case gig::dimension_portamento:
76 return "Portamento Ctrl.";
77 case gig::dimension_sostenutopedal:
78 return "Sostenuto Pedal";
79 case gig::dimension_softpedal:
80 return "Soft Pedal";
81 case gig::dimension_genpurpose5:
82 return "General Purpose Ctrl. 5";
83 case gig::dimension_genpurpose6:
84 return "General Purpose Ctrl. 6";
85 case gig::dimension_genpurpose7:
86 return "General Purpose Ctrl. 7";
87 case gig::dimension_genpurpose8:
88 return "General Purpose Ctrl. 8";
89 case gig::dimension_effect1depth:
90 return "Effect 1 Depth";
91 case gig::dimension_effect2depth:
92 return "Effect 2 Depth";
93 case gig::dimension_effect3depth:
94 return "Effect 3 Depth";
95 case gig::dimension_effect4depth:
96 return "Effect 4 Depth";
97 case gig::dimension_effect5depth:
98 return "Effect 5 Depth";
99 default:
100 sprintf(buf, "Unknown Type (0x%x) !!!", d);
101 return buf;
102 }
103 }
104
105 // returns a human readable description of the given dimension
106 static Glib::ustring __dimDescriptionAsString(gig::dimension_t d) {
107 switch (d) {
108 case gig::dimension_none:
109 return "Dimension not in use";
110 case gig::dimension_samplechannel:
111 return "If used sample has more than one channel (thus is not mono)";
112 case gig::dimension_layer:
113 return "For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers";
114 case gig::dimension_velocity:
115 return "Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined)";
116 case gig::dimension_channelaftertouch:
117 return "Channel Key Pressure";
118 case gig::dimension_releasetrigger:
119 return "Special dimension for triggering samples on releasing a key";
120 case gig::dimension_keyboard:
121 return "Dimension for keyswitching (keyboard)";
122 case gig::dimension_roundrobin:
123 return "Different samples triggered each time a note is played, dimension regions selected in sequence";
124 case gig::dimension_random:
125 return "Different samples triggered each time a note is played, random order";
126 case gig::dimension_smartmidi:
127 return "For MIDI tools like legato and repetition mode";
128 case gig::dimension_roundrobinkeyboard:
129 return "Different samples triggered each time a note is played, any key advances the counter";
130 case gig::dimension_modwheel:
131 return "MIDI Controller 1";
132 case gig::dimension_breath:
133 return "MIDI Controller 2";
134 case gig::dimension_foot:
135 return "MIDI Controller 4";
136 case gig::dimension_portamentotime:
137 return "MIDI Controller 5";
138 case gig::dimension_effect1:
139 return "MIDI Controller 12";
140 case gig::dimension_effect2:
141 return "MIDI Controller 13";
142 case gig::dimension_genpurpose1:
143 return "Slider, MIDI Controller 16";
144 case gig::dimension_genpurpose2:
145 return "Slider, MIDI Controller 17";
146 case gig::dimension_genpurpose3:
147 return "Slider, MIDI Controller 18";
148 case gig::dimension_genpurpose4:
149 return "Slider, MIDI Controller 19";
150 case gig::dimension_sustainpedal:
151 return "MIDI Controller 64";
152 case gig::dimension_portamento:
153 return "MIDI Controller 65";
154 case gig::dimension_sostenutopedal:
155 return "MIDI Controller 66";
156 case gig::dimension_softpedal:
157 return "MIDI Controller 67";
158 case gig::dimension_genpurpose5:
159 return "Button, MIDI Controller 80";
160 case gig::dimension_genpurpose6:
161 return "Button, MIDI Controller 81";
162 case gig::dimension_genpurpose7:
163 return "Button, MIDI Controller 82";
164 case gig::dimension_genpurpose8:
165 return "Button, MIDI Controller 83";
166 case gig::dimension_effect1depth:
167 return "MIDI Controller 91";
168 case gig::dimension_effect2depth:
169 return "MIDI Controller 92";
170 case gig::dimension_effect3depth:
171 return "MIDI Controller 93";
172 case gig::dimension_effect4depth:
173 return "MIDI Controller 94";
174 case gig::dimension_effect5depth:
175 return "MIDI Controller 95";
176 default:
177 return "Please report this !!!";
178 }
179 }
180
181 DimensionManager::DimensionManager() :
182 addButton(Gtk::Stock::ADD), removeButton(Gtk::Stock::REMOVE)
183 {
184 set_title("Dimensions of selected Region");
185 add(vbox);
186 scrolledWindow.add(treeView);
187 vbox.pack_start(scrolledWindow);
188 scrolledWindow.show();
189 vbox.pack_start(buttonBox);
190 buttonBox.set_layout(Gtk::BUTTONBOX_END);
191 buttonBox.set_border_width(5);
192 buttonBox.show();
193 buttonBox.pack_start(addButton);
194 buttonBox.pack_start(removeButton);
195 addButton.show();
196 removeButton.show();
197
198 // setup the table
199 refTableModel = Gtk::ListStore::create(tableModel);
200 treeView.set_model(refTableModel);
201 treeView.append_column("Dimension Type", tableModel.m_dim_type);
202 treeView.append_column("Bits", tableModel.m_bits);
203 treeView.append_column("Zones", tableModel.m_zones);
204 treeView.append_column("Description", tableModel.m_description);
205 treeView.show();
206
207 addButton.signal_clicked().connect(
208 sigc::mem_fun(*this, &DimensionManager::addDimension)
209 );
210
211 removeButton.signal_clicked().connect(
212 sigc::mem_fun(*this, &DimensionManager::removeDimension)
213 );
214
215 show_all_children();
216 }
217
218 // update all GUI elements according to current gig::Region informations
219 void DimensionManager::refreshManager() {
220 refTableModel->clear();
221 for (int i = 0; i < region->Dimensions; i++) {
222 gig::dimension_def_t* dim = &region->pDimensionDefinitions[i];
223 Gtk::TreeModel::Row row = *(refTableModel->append());
224 row[tableModel.m_dim_type] = __dimTypeAsString(dim->dimension);
225 row[tableModel.m_bits] = dim->bits;
226 row[tableModel.m_zones] = 1 << dim->bits; //TODO: for now we calculate it here until libgig always ensures 'zones' to be correct
227 row[tableModel.m_description] = __dimDescriptionAsString(dim->dimension);
228 row[tableModel.m_definition] = dim;
229 }
230 }
231
232 void DimensionManager::show(gig::Region* region) {
233 this->region = region;
234 refreshManager();
235 Gtk::Window::show();
236 deiconify();
237 }
238
239 void DimensionManager::addDimension() {
240 try {
241 Gtk::Dialog dialog("New Dimension", true /*modal*/);
242 // add dimension type combo box to the dialog
243 Glib::RefPtr<Gtk::ListStore> refComboModel = Gtk::ListStore::create(comboModel);
244 for (int i = 0x01; i < 0xff; i++) {
245 Glib::ustring sType =
246 __dimTypeAsString(static_cast<gig::dimension_t>(i));
247 if (sType.find("Unknown") != 0) {
248 Gtk::TreeModel::Row row = *(refComboModel->append());
249 row[comboModel.m_type_id] = i;
250 row[comboModel.m_type_name] = sType;
251 }
252 }
253 Gtk::ComboBox comboDimType;
254 comboDimType.set_model(refComboModel);
255 comboDimType.pack_start(comboModel.m_type_id);
256 comboDimType.pack_start(comboModel.m_type_name);
257 dialog.get_vbox()->pack_start(comboDimType);
258 comboDimType.show();
259 // add zones combo box to the dialog
260 Gtk::ComboBoxText comboZones;
261 for (int i = 1; i <= 7; i++) { //FIXME: is 7 the correct amount of max. bits ???
262 char buf[64];
263 sprintf(buf, "%d Zones (%d Bits)", 1 << i, i);
264 comboZones.append_text(buf);
265 }
266 dialog.get_vbox()->pack_start(comboZones);
267 comboZones.show();
268 // add OK and CANCEL buttons to the dialog
269 dialog.add_button(Gtk::Stock::OK, 0);
270 dialog.add_button(Gtk::Stock::CANCEL, 1);
271 dialog.show_all_children();
272 if (!dialog.run()) { // OK selected ...
273 Gtk::TreeModel::iterator iterType = comboDimType.get_active();
274 if (!iterType) return;
275 Gtk::TreeModel::Row rowType = *iterType;
276 if (!rowType) return;
277 gig::dimension_def_t dim;
278 int iTypeID = rowType[comboModel.m_type_id];
279 dim.dimension = static_cast<gig::dimension_t>(iTypeID);
280 if (comboZones.get_active_row_number() < 0) return;
281 dim.bits = comboZones.get_active_row_number() + 1;
282 dim.zones = 1 << dim.bits; //TODO: support zones != pow(2,bits) - feature of gig v3
283 printf(
284 "Adding dimension (type=0x%x, bits=%d, zones=%d)\n",
285 dim.dimension, dim.bits, dim.zones
286 );
287 // add the new dimension to the region
288 // (implicitly creates new dimension regions)
289 region->AddDimension(&dim);
290 // let everybody know there was a change
291 articulation_changed_signal.emit();
292 // update all GUI elements
293 refreshManager();
294 }
295 } catch (RIFF::Exception e) {
296 Glib::ustring txt = "Could not add dimension: " + e.Message;
297 Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
298 msg.run();
299 }
300 }
301
302 void DimensionManager::removeDimension() {
303 Glib::RefPtr<Gtk::TreeSelection> sel = treeView.get_selection();
304 Gtk::TreeModel::iterator it = sel->get_selected();
305 if (it) {
306 try {
307 // remove selected dimension
308 Gtk::TreeModel::Row row = *it;
309 gig::dimension_def_t* dim = row[tableModel.m_definition];
310 region->DeleteDimension(dim);
311 // remove respective row from table
312 refTableModel->erase(it);
313 // let everybody know there was a change
314 articulation_changed_signal.emit();
315 } catch (RIFF::Exception e) {
316 Glib::ustring txt = "Could not remove dimension: " + e.Message;
317 Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
318 msg.run();
319 }
320 }
321 }

  ViewVC Help
Powered by ViewVC