/[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 1623 - (hide annotations) (download)
Fri Jan 4 19:42:45 2008 UTC (16 years, 2 months ago) by persson
File size: 13654 byte(s)
* gig files where regions are not internally ordered are now handled
* the resize mouse pointer is not shown anymore for regions that can't
  be resized
* the region and dimregion chooser widgets are now resizable
* bugfix: sometimes you could not delete more than one dimension
* filter headers are now also greyed out when the filter is inactive

1 schoenebeck 1225 /* -*- c++ -*-
2 persson 1623 * Copyright (C) 2006-2008 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    
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 schoenebeck 1411 vbox.pack_start(buttonBox, Gtk::PACK_SHRINK);
190 schoenebeck 1225 buttonBox.set_layout(Gtk::BUTTONBOX_END);
191     buttonBox.set_border_width(5);
192     buttonBox.show();
193 schoenebeck 1411 buttonBox.pack_start(addButton, Gtk::PACK_SHRINK);
194     buttonBox.pack_start(removeButton, Gtk::PACK_SHRINK);
195 schoenebeck 1225 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 persson 1303 treeView.append_column("Bits", tableModel.m_bits);
203     treeView.append_column("Zones", tableModel.m_zones);
204 schoenebeck 1225 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 schoenebeck 1322 // notify everybody that we're going to update the region
288     region_to_be_changed_signal.emit(region);
289 schoenebeck 1225 // add the new dimension to the region
290     // (implicitly creates new dimension regions)
291     region->AddDimension(&dim);
292     // let everybody know there was a change
293 schoenebeck 1322 region_changed_signal.emit(region);
294 schoenebeck 1225 // update all GUI elements
295     refreshManager();
296     }
297     } catch (RIFF::Exception e) {
298 schoenebeck 1322 // notify that the changes are over (i.e. to avoid dead locks)
299     region_changed_signal.emit(region);
300     // show error message
301 schoenebeck 1225 Glib::ustring txt = "Could not add dimension: " + e.Message;
302     Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
303     msg.run();
304     }
305     }
306    
307     void DimensionManager::removeDimension() {
308     Glib::RefPtr<Gtk::TreeSelection> sel = treeView.get_selection();
309     Gtk::TreeModel::iterator it = sel->get_selected();
310     if (it) {
311     try {
312 schoenebeck 1322 // notify everybody that we're going to update the region
313     region_to_be_changed_signal.emit(region);
314 schoenebeck 1225 // remove selected dimension
315     Gtk::TreeModel::Row row = *it;
316     gig::dimension_def_t* dim = row[tableModel.m_definition];
317     region->DeleteDimension(dim);
318     // let everybody know there was a change
319 schoenebeck 1322 region_changed_signal.emit(region);
320 persson 1623 // update all GUI elements
321     refreshManager();
322 schoenebeck 1225 } catch (RIFF::Exception e) {
323 schoenebeck 1322 // notify that the changes are over (i.e. to avoid dead locks)
324     region_changed_signal.emit(region);
325     // show error message
326 schoenebeck 1225 Glib::ustring txt = "Could not remove dimension: " + e.Message;
327     Gtk::MessageDialog msg(*this, txt, false, Gtk::MESSAGE_ERROR);
328     msg.run();
329     }
330     }
331     }

  ViewVC Help
Powered by ViewVC