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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2169 - (show annotations) (download)
Sun Mar 6 07:51:04 2011 UTC (13 years, 1 month ago) by persson
File size: 10164 byte(s)
* ported to gtkmm 3, keeping compatibility with gtkmm 2

1 /*
2 * Copyright (C) 2006-2011 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 <cstring>
21
22 #include "paramedit.h"
23
24 #include "global.h"
25 #include "compat.h"
26
27 namespace {
28 const char* const controlChangeTexts[] = {
29 _("none"), _("channelaftertouch"), _("velocity"),
30 0,
31 _("modwheel"), // "Modulation Wheel or Lever",
32 _("breath"), // "Breath Controller",
33 0,
34 _("foot"), // "Foot Controller",
35 _("portamentotime"), // "Portamento Time",
36 0, 0, 0, 0, 0, 0,
37 _("effect1"), // "Effect Control 1",
38 _("effect2"), // "Effect Control 2",
39 0, 0,
40 _("genpurpose1"), // "General Purpose Controller 1",
41 _("genpurpose2"), // "General Purpose Controller 2",
42 _("genpurpose3"), // "General Purpose Controller 3",
43 _("genpurpose4"), // "General Purpose Controller 4",
44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0,
47 _("sustainpedal"), // "Damper Pedal on/off (Sustain)",
48 _("portamento"), // "Portamento On/Off",
49 _("sostenuto"), // "Sustenuto On/Off",
50 _("softpedal"), // "Soft Pedal On/Off",
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52 _("genpurpose5"), // "General Purpose Controller 5",
53 _("genpurpose6"), // "General Purpose Controller 6",
54 _("genpurpose7"), // "General Purpose Controller 7",
55 _("genpurpose8"), // "General Purpose Controller 8",
56 0, 0, 0, 0, 0, 0, 0,
57 _("effect1depth"), // "Effects 1 Depth",
58 _("effect2depth"), // "Effects 2 Depth",
59 _("effect3depth"), // "Effects 3 Depth",
60 _("effect4depth"), // "Effects 4 Depth",
61 _("effect5depth"), // "Effects 5 Depth"
62 };
63 }
64
65 LabelWidget::LabelWidget(const char* labelText, Gtk::Widget& widget) :
66 label(Glib::ustring(labelText) + ":"),
67 widget(widget)
68 {
69 label.set_alignment(Gtk::ALIGN_START);
70 }
71
72 void LabelWidget::set_sensitive(bool sensitive)
73 {
74 label.set_sensitive(sensitive);
75 widget.set_sensitive(sensitive);
76 }
77
78 NumEntry::NumEntry(const char* labelText, double lower, double upper,
79 int decimals) :
80 LabelWidget(labelText, box),
81 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
82 adjust(lower, lower, upper, 1, 10),
83 #else
84 adjust(Gtk::Adjustment::create(lower, lower, upper, 1, 10)),
85 #endif
86 scale(adjust),
87 spinbutton(adjust)
88 {
89 spinbutton.set_digits(decimals);
90 spinbutton.set_value(0);
91 scale.set_draw_value(false);
92 box.pack_start(spinbutton, Gtk::PACK_SHRINK);
93 box.add(scale);
94 }
95
96 NumEntryGain::NumEntryGain(const char* labelText,
97 double lower, double upper,
98 int decimals, double coeff) :
99 NumEntry(labelText, lower, upper, decimals),
100 value(0),
101 coeff(coeff),
102 connected(true)
103 {
104 spinbutton.signal_value_changed().connect(
105 sigc::mem_fun(*this, &NumEntryGain::value_changed));
106 }
107
108 void NumEntryGain::value_changed()
109 {
110 if (!connected) return;
111
112 const double f = pow(10, spinbutton.get_digits());
113 int new_value = round_to_int(spinbutton.get_value() * f);
114 if (new_value != round_to_int(value / coeff * f)) {
115 value = round_to_int(new_value / f * coeff);
116 sig_changed();
117 }
118 }
119
120 void NumEntryGain::set_value(int32_t value)
121 {
122 if (value != this->value) {
123 this->value = value;
124
125 connected = false;
126 bool plus6 = value < 0;
127 spinbutton.set_value(plus6 ? 0 : value / coeff);
128 set_sensitive(!plus6);
129 connected = true;
130
131 sig_changed();
132 }
133 }
134
135
136 BoolEntryPlus6::BoolEntryPlus6(const char* labelText, NumEntryGain& eGain, int32_t plus6value) :
137 LabelWidget(labelText, checkbutton),
138 checkbutton(labelText),
139 eGain(eGain),
140 plus6value(plus6value)
141 {
142 checkbutton.signal_toggled().connect(
143 sigc::mem_fun(*this, &BoolEntryPlus6::value_changed));
144 }
145
146 void BoolEntryPlus6::value_changed()
147 {
148 if (checkbutton.get_active()) eGain.set_value(plus6value);
149 else if (eGain.get_value() < 0) eGain.set_value(0);
150 }
151
152 int32_t BoolEntryPlus6::get_value() const
153 {
154 return eGain.get_value();
155 }
156
157 void BoolEntryPlus6::set_value(int32_t value)
158 {
159 checkbutton.set_active(value < 0);
160 }
161
162 NumEntryPermille::NumEntryPermille(const char* labelText,
163 double lower, double upper, int decimals) :
164 NumEntry(labelText, lower, upper, decimals),
165 value(0)
166 {
167 spinbutton.signal_value_changed().connect(
168 sigc::mem_fun(*this, &NumEntryPermille::value_changed));
169 }
170
171 void NumEntryPermille::value_changed()
172 {
173 uint16_t new_value = uint16_t(spinbutton.get_value() * 10 + 0.5);
174 if (new_value != value) {
175 value = uint16_t(spinbutton.get_value() * 10 + 0.5);
176 sig_changed();
177 }
178 }
179
180 void NumEntryPermille::set_value(uint16_t value)
181 {
182 if (value != this->value) {
183 spinbutton.set_value(value / 10.0);
184 }
185 }
186
187
188 NoteEntry::NoteEntry(const char* labelText) :
189 NumEntryTemp<uint8_t>(labelText)
190 {
191 spinbutton.signal_input().connect(
192 sigc::mem_fun(*this, &NoteEntry::on_input));
193 spinbutton.signal_output().connect(
194 sigc::mem_fun(*this, &NoteEntry::on_output));
195 }
196
197 const char* notes[] = {
198 _("C"), _("C#"), _("D"), _("D#"), _("E"), _("F"),_("F#"),
199 _("G"), _("G#"), _("A"), _("A#"), _("B")
200 };
201
202
203 // Convert the Entry text to a number
204 int NoteEntry::on_input(double* new_value)
205 {
206 const char* str = spinbutton.get_text().c_str();
207
208 int i;
209 for (i = 11 ; i >= 0 ; i--) {
210 if (strncmp(str, notes[i], strlen(notes[i])) == 0) break;
211 }
212 if (i >= 0) {
213 char* endptr;
214 long x = strtol(str + strlen(notes[i]), &endptr, 10);
215 if (endptr != str + strlen(notes[i])) {
216 *new_value = i + (x + 1) * 12;
217 return true;
218 }
219 }
220 return Gtk::INPUT_ERROR;
221 }
222
223 // Convert the Adjustment position to text
224 bool NoteEntry::on_output()
225 {
226 int x = int(spinbutton.get_adjustment()->get_value() + 0.5);
227 char buf[10];
228 sprintf(buf, "%s%d", notes[x % 12], x / 12 - 1);
229 spinbutton.set_text(buf);
230 return true;
231 }
232
233 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :
234 LabelWidget(labelText, align),
235 align(0, 0, 0, 0)
236 {
237 for (int i = 0 ; i < 99 ; i++) {
238 if (controlChangeTexts[i]) {
239 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
240 combobox.append_text(controlChangeTexts[i]);
241 #else
242 combobox.append(controlChangeTexts[i]);
243 #endif
244 }
245 }
246 combobox.signal_changed().connect(
247 sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));
248 align.add(combobox);
249 value.type = gig::leverage_ctrl_t::type_none;
250 value.controller_number = 0;
251 }
252
253 void ChoiceEntryLeverageCtrl::value_changed()
254 {
255 int rowno = combobox.get_active_row_number();
256 switch (rowno)
257 {
258 case -1:
259 break;
260 case 0:
261 value.type = gig::leverage_ctrl_t::type_none;
262 break;
263 case 1:
264 value.type = gig::leverage_ctrl_t::type_channelaftertouch;
265 break;
266 case 2:
267 value.type = gig::leverage_ctrl_t::type_velocity;
268 break;
269 default:
270 value.type = gig::leverage_ctrl_t::type_controlchange;
271 int x = 3;
272 for (uint cc = 0 ; cc < 96 ; cc++) {
273 if (controlChangeTexts[cc + 3]) {
274 if (rowno == x) {
275 value.controller_number = cc;
276 break;
277 }
278 x++;
279 }
280 }
281 break;
282 }
283 if (rowno >= 0) sig_changed();
284 }
285
286 void ChoiceEntryLeverageCtrl::set_value(gig::leverage_ctrl_t value)
287 {
288 int x;
289 switch (value.type)
290 {
291 case gig::leverage_ctrl_t::type_none:
292 x = 0;
293 break;
294 case gig::leverage_ctrl_t::type_channelaftertouch:
295 x = 1;
296 break;
297 case gig::leverage_ctrl_t::type_velocity:
298 x = 2;
299 break;
300 case gig::leverage_ctrl_t::type_controlchange:
301 x = -1;
302 for (uint cc = 0 ; cc < 96 ; cc++) {
303 if (controlChangeTexts[cc + 3]) {
304 x++;
305 if (value.controller_number == cc) {
306 x += 3;
307 break;
308 }
309 }
310 }
311 break;
312 default:
313 x = -1;
314 break;
315 }
316 combobox.set_active(x);
317 }
318
319
320 BoolEntry::BoolEntry(const char* labelText) :
321 LabelWidget(labelText, checkbutton),
322 checkbutton(labelText)
323 {
324 checkbutton.signal_toggled().connect(sig_changed.make_slot());
325 }
326
327
328 StringEntry::StringEntry(const char* labelText) :
329 LabelWidget(labelText, entry)
330 {
331 entry.signal_changed().connect(sig_changed.make_slot());
332 }
333
334 StringEntryMultiLine::StringEntryMultiLine(const char* labelText) :
335 LabelWidget(labelText, frame)
336 {
337 text_buffer = text_view.get_buffer();
338 frame.set_shadow_type(Gtk::SHADOW_IN);
339 frame.add(text_view);
340 text_buffer->signal_changed().connect(sig_changed.make_slot());
341 }
342
343 gig::String StringEntryMultiLine::get_value() const
344 {
345 Glib::ustring value = text_buffer->get_text();
346 for (int i = 0 ; (i = value.find("\x0a", i)) >= 0 ; i += 2)
347 value.replace(i, 1, "\x0d\x0a");
348 return value;
349 }
350
351 void StringEntryMultiLine::set_value(gig::String value)
352 {
353 for (int i = 0 ; (i = value.find("\x0d\x0a", i, 2)) >= 0 ; i++)
354 value.replace(i, 2, "\x0a");
355 text_buffer->set_text(value);
356 }

  ViewVC Help
Powered by ViewVC