/[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 2151 - (show annotations) (download)
Sun Nov 21 12:38:41 2010 UTC (13 years, 3 months ago) by persson
File size: 9828 byte(s)
* use Cairo instead of deprecated gdk drawing primitives
* avoid deprecated gtk methods when using newer gtk versions
* raised minimum supported gtkmm version to 2.8

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

  ViewVC Help
Powered by ViewVC