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

Contents of /gigedit/trunk/src/gigedit/regionchooser.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: 24244 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 /*
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 "regionchooser.h"
21 #include <gdkmm/cursor.h>
22 #include <gtkmm/stock.h>
23 #include <gtkmm/spinbutton.h>
24 #include <gtkmm/dialog.h>
25 #include <libintl.h>
26 #include <math.h>
27
28 #define _(String) gettext(String)
29
30 RegionChooser::RegionChooser()
31 {
32 Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();
33
34 red = Gdk::Color("#8070ff");
35 grey1 = Gdk::Color("#b0b0b0");
36
37 colormap->alloc_color(red);
38 colormap->alloc_color(grey1);
39 instrument = 0;
40 region = 0;
41 resize.active = false;
42 move.active = false;
43 cursor_is_resize = false;
44 h1 = 20;
45 width = 800;
46
47 actionGroup = Gtk::ActionGroup::create();
48 actionGroup->add(Gtk::Action::create("Properties",
49 Gtk::Stock::PROPERTIES),
50 sigc::mem_fun(*this,
51 &RegionChooser::show_region_properties));
52 actionGroup->add(Gtk::Action::create("Remove", Gtk::Stock::REMOVE),
53 sigc::mem_fun(*this, &RegionChooser::delete_region));
54 actionGroup->add(Gtk::Action::create("Add", Gtk::Stock::ADD),
55 sigc::mem_fun(*this, &RegionChooser::add_region));
56 actionGroup->add(Gtk::Action::create("Dimensions", _("Dimensions...")),
57 sigc::mem_fun(*this, &RegionChooser::manage_dimensions));
58
59 uiManager = Gtk::UIManager::create();
60 uiManager->insert_action_group(actionGroup);
61 Glib::ustring ui_info =
62 "<ui>"
63 " <popup name='PopupMenuInsideRegion'>"
64 " <menuitem action='Properties'/>"
65 " <menuitem action='Dimensions'/>"
66 " <menuitem action='Remove'/>"
67 " </popup>"
68 " <popup name='PopupMenuOutsideRegion'>"
69 " <menuitem action='Add'/>"
70 " </popup>"
71 "</ui>";
72 uiManager->add_ui_from_string(ui_info);
73
74 popup_menu_inside_region = dynamic_cast<Gtk::Menu*>(
75 uiManager->get_widget("/PopupMenuInsideRegion"));
76 popup_menu_outside_region = dynamic_cast<Gtk::Menu*>(
77 uiManager->get_widget("/PopupMenuOutsideRegion"));
78
79 add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
80 Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK);
81
82 dimensionManager.articulation_changed_signal.connect(
83 sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed)
84 );
85 }
86
87 RegionChooser::~RegionChooser()
88 {
89 }
90
91 void RegionChooser::on_realize()
92 {
93 // We need to call the base on_realize()
94 Gtk::DrawingArea::on_realize();
95
96 // Now we can allocate any additional resources we need
97 Glib::RefPtr<Gdk::Window> window = get_window();
98 gc = Gdk::GC::create(window);
99 window->clear();
100 }
101
102 bool RegionChooser::on_expose_event(GdkEventExpose* event)
103 {
104 Glib::RefPtr<Gdk::Window> window = get_window();
105 window->clear();
106 const int h = 40;
107 const int w = width - 1;
108 const int bh = int(h * 0.55);
109
110 Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
111 Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();
112
113 Glib::RefPtr<Pango::Context> context = get_pango_context();
114 Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
115
116 window->draw_rectangle(black, false, 0, h1, w, h - 1);
117 gc->set_foreground(grey1);
118 int x1 = int(w * 20.5 / 128.0 + 0.5);
119 int x2 = int(w * 109.5 / 128.0 + 0.5);
120 window->draw_rectangle(gc, true, 1, h1 + 1,
121 x1 - 1, h - 2);
122 window->draw_rectangle(white, true, x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);
123 window->draw_rectangle(gc, true, x2 + 1, h1 + 1,
124 w - x2 - 1, h - 2);
125 int octave = -1;
126 for (int i = 0 ; i < 128 ; i++) {
127 int note = (i + 3) % 12;
128 int x = int(w * i / 128.0 + 0.5);
129
130 if (note == 1 || note == 4 || note == 6 || note == 9 || note == 11) {
131 int x2 = int(w * (i + 0.5) / 128.0 + 0.5);
132 window->draw_line(black, x2, h1 + bh, x2, h1 + h);
133
134 int x3 = int(w * (i + 1) / 128.0 + 0.5);
135 window->draw_rectangle(black, true, x, h1 + 1, x3 - x + 1, bh);
136 } else if (note == 3 || note == 8) {
137 window->draw_line(black, x, h1 + 1, x, h1 + h);
138 }
139 if (note == 3) {
140 char buf[30];
141 sprintf(buf, "<span size=\"x-small\">%d</span>", octave);
142 layout->set_markup(buf);
143 Pango::Rectangle rectangle = layout->get_logical_extents();
144 double text_w = double(rectangle.get_width()) / Pango::SCALE;
145 double text_h = double(rectangle.get_height()) / Pango::SCALE;
146 double x2 = w * (i + 0.75) / 128.0;
147 window->draw_layout(black, int(x2 - text_w / 2 + 1),
148 int(h1 + h - text_h + 0.5), layout);
149 octave++;
150 }
151 }
152
153 if (instrument) {
154 int i = 0;
155 gig::Region *next_region;
156 int x3 = -1;
157 for (gig::Region *r = instrument->GetFirstRegion() ;
158 r ;
159 r = next_region) {
160
161 if (x3 < 0) x3 = int(w * (r->KeyRange.low) / 128.0 + 0.5);
162 next_region = instrument->GetNextRegion();
163 if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
164 int x2 = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);
165 window->draw_line(black, x3, 0, x2, 0);
166 window->draw_line(black, x3, h1 - 1, x2, h1 - 1);
167 window->draw_line(black, x2, 1, x2, h1 - 2);
168 window->draw_rectangle(white, true, x3 + 1, 1, x2 - x3 - 1, h1 - 2);
169 x3 = -1;
170 }
171 i++;
172 }
173
174 for (gig::Region *r = instrument->GetFirstRegion() ;
175 r ;
176 r = instrument->GetNextRegion()) {
177 int x = int(w * (r->KeyRange.low) / 128.0 + 0.5);
178 window->draw_line(black, x, 1, x, h1 - 2);
179 }
180
181 if (region) {
182 int x1 = int(w * (region->KeyRange.low) / 128.0 + 0.5);
183 int x2 = int(w * (region->KeyRange.high + 1) / 128.0 + 0.5);
184 gc->set_foreground(red);
185 window->draw_rectangle(gc, true, x1 + 1, 1, x2 - x1 - 1, h1 - 2);
186 }
187 }
188 return true;
189 }
190
191
192 void RegionChooser::on_size_request(GtkRequisition* requisition)
193 {
194 *requisition = GtkRequisition();
195 requisition->height = 40 + 20;
196 requisition->width = 500;
197 }
198
199
200 // not used
201 void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)
202 {
203 const int h = 40;
204 const int w = width;
205 const int bh = int(h * 0.55);
206
207 Glib::RefPtr<Gdk::Window> window = get_window();
208 gc->set_foreground(color);
209
210 for (int i = from ; i < to ; i++) {
211 int note = (i + 3) % 12;
212 int x = int(w * i / 128.0 + 0.5) + 1;
213 int x2 = int(w * (i + 1.5) / 128.0 + 0.5);
214 int x3 = int(w * (i + 1) / 128.0 + 0.5);
215 int x4 = int(w * (i - 0.5) / 128 + 0.5) + 1;
216 int w1 = x3 - x;
217 switch (note) {
218 case 0: case 5: case 10:
219 window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);
220 window->draw_rectangle(gc, true, x4, h1 + bh + 1, x2 - x4, h - bh - 2);
221 break;
222 case 2: case 7:
223 window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);
224 window->draw_rectangle(gc, true, x4, h1 + bh + 1, x3 - x4, h - bh - 2);
225 break;
226 case 3: case 8:
227 window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);
228 window->draw_rectangle(gc, true, x, h1 + bh + 1, x2 - x, h - bh - 2);
229 break;
230 default:
231 window->draw_rectangle(gc, true, x, h1 + 1, w1, bh - 1);
232 break;
233 }
234 }
235 }
236
237 void RegionChooser::set_instrument(gig::Instrument* instrument)
238 {
239 this->instrument = instrument;
240 region = instrument ? instrument->GetFirstRegion() : 0;
241 queue_draw();
242 region_selected();
243 }
244
245 bool RegionChooser::on_button_release_event(GdkEventButton* event)
246 {
247 if (resize.active) {
248 get_window()->pointer_ungrab(event->time);
249 resize.active = false;
250
251 if (resize.mode == resize.moving_high_limit) {
252 if (resize.region->KeyRange.high != resize.pos - 1) {
253 resize.region->KeyRange.high = resize.pos - 1;
254 instrument_changed();
255 }
256 } else if (resize.mode == resize.moving_low_limit) {
257 if (resize.region->KeyRange.low != resize.pos) {
258 resize.region->KeyRange.low = resize.pos;
259 instrument_changed();
260 }
261 }
262
263 if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
264 get_window()->set_cursor();
265 cursor_is_resize = false;
266 }
267 } else if (move.active) {
268 get_window()->pointer_ungrab(event->time);
269 move.active = false;
270
271 if (move.pos) {
272 region->KeyRange.low += move.pos;
273 region->KeyRange.high += move.pos;
274
275 // find the r which is the first one to the right of region
276 // at its new position
277 gig::Region* r;
278 gig::Region* prev_region = 0;
279 for (r = instrument->GetFirstRegion() ; r ; r = instrument->GetNextRegion()) {
280 if (r->KeyRange.low > region->KeyRange.low) break;
281 prev_region = r;
282 }
283
284 // place region before r if it's not already there
285 if (prev_region != region) {
286 instrument->MoveRegion(region, r);
287 }
288 }
289
290 if (is_in_resize_zone(event->x, event->y)) {
291 get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
292 cursor_is_resize = true;
293 }
294 }
295 return true;
296 }
297
298 bool RegionChooser::on_button_press_event(GdkEventButton* event)
299 {
300 if (!instrument) return true;
301
302 int k = int(event->x / (width - 1) * 128.0);
303
304 if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
305 gig::Region* r = get_region(k);
306 if (r) {
307 region = r;
308 queue_draw();
309 region_selected();
310 popup_menu_inside_region->popup(event->button, event->time);
311 } else {
312 new_region_pos = k;
313 popup_menu_outside_region->popup(event->button, event->time);
314 }
315 } else {
316 if (is_in_resize_zone(event->x, event->y)) {
317 get_window()->pointer_grab(false,
318 Gdk::BUTTON_RELEASE_MASK |
319 Gdk::POINTER_MOTION_MASK |
320 Gdk::POINTER_MOTION_HINT_MASK,
321 Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW), event->time);
322 resize.active = true;
323 } else {
324 gig::Region* r = get_region(k);
325 if (r) {
326 region = r;
327 queue_draw();
328 region_selected();
329
330 get_window()->pointer_grab(false,
331 Gdk::BUTTON_RELEASE_MASK |
332 Gdk::POINTER_MOTION_MASK |
333 Gdk::POINTER_MOTION_HINT_MASK,
334 Gdk::Cursor(Gdk::FLEUR), event->time);
335 move.active = true;
336 move.from_x = event->x;
337 move.pos = 0;
338 }
339 }
340 }
341 return true;
342 }
343
344 gig::Region* RegionChooser::get_region(int key)
345 {
346 gig::Region* prev_region = 0;
347 gig::Region* next_region;
348 for (gig::Region *r = instrument->GetFirstRegion() ; r ;
349 r = next_region) {
350 next_region = instrument->GetNextRegion();
351
352 if (key < r->KeyRange.low) return 0;
353 if (key <= r->KeyRange.high) {
354 move.touch_left = prev_region && prev_region->KeyRange.high + 1 == r->KeyRange.low;
355 move.touch_right = next_region && r->KeyRange.high + 1 == next_region->KeyRange.low;
356 return r;
357 }
358 prev_region = r;
359 }
360 return 0;
361 }
362
363 void RegionChooser::motion_resize_region(int x, int y)
364 {
365 const int w = width - 1;
366 Glib::RefPtr<Gdk::Window> window = get_window();
367
368 int k = int(double(x) / w * 128.0 + 0.5);
369
370 if (k < resize.min) k = resize.min;
371 else if (k > resize.max) k = resize.max;
372
373 if (k != resize.pos) {
374 if (resize.mode == resize.undecided) {
375 if (k < resize.pos) {
376 // edit high limit of prev_region
377 resize.max = resize.region->KeyRange.low;
378 resize.region = resize.prev_region;
379 resize.mode = resize.moving_high_limit;
380 } else {
381 // edit low limit of region
382 resize.min = resize.prev_region->KeyRange.high + 1;
383 resize.mode = resize.moving_low_limit;
384 }
385 }
386 Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
387 Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();
388 if (region == resize.region) {
389 gc->set_foreground(red);
390 white = gc;
391 }
392 Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);
393 int prevx = int(w * resize.pos / 128.0 + 0.5);
394 x = int(w * k / 128.0 + 0.5);
395
396 if (resize.mode == resize.moving_high_limit) {
397 if (k > resize.pos) {
398 window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);
399 window->draw_line(black, prevx, 0, x, 0);
400 window->draw_line(black, prevx, h1 - 1, x, h1 - 1);
401 } else {
402 int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);
403 window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);
404 }
405 } else {
406 if (k < resize.pos) {
407 window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);
408 window->draw_line(black, x, 0, prevx, 0);
409 window->draw_line(black, x, h1 - 1, prevx, h1 - 1);
410 } else {
411 int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);
412 window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);
413 }
414 }
415 window->draw_line(black, x, 1, x, h1 - 2);
416 resize.pos = k;
417 }
418 }
419
420 void RegionChooser::motion_move_region(int x, int y)
421 {
422 const int w = width - 1;
423 Glib::RefPtr<Gdk::Window> window = get_window();
424
425 int k = int(double(x - move.from_x) / w * 128.0 + 0.5);
426 if (k == move.pos) return;
427 int new_k;
428 bool new_touch_left;
429 bool new_touch_right;
430 int a = 0;
431 if (k > move.pos) {
432 for (gig::Region* r = instrument->GetFirstRegion() ; ;
433 r = instrument->GetNextRegion()) {
434 if (r != region) {
435 int b = r ? r->KeyRange.low : 128;
436
437 // gap: from a to b (not inclusive b)
438
439 if (region->KeyRange.high + move.pos >= b) {
440 // not found the current gap yet, just continue
441 } else {
442
443 if (a > region->KeyRange.low + k) {
444 // this gap is too far to the right, break
445 break;
446 }
447
448 int newhigh = std::min(region->KeyRange.high + k, b - 1);
449 int newlo = newhigh - (region->KeyRange.high - region->KeyRange.low);
450
451 if (newlo >= a) {
452 // yes it fits - it's a candidate
453 new_k = newlo - region->KeyRange.low;
454 new_touch_left = a > 0 && a == newlo;
455 new_touch_right = b < 128 && newhigh + 1 == b;
456 }
457 }
458 if (!r) break;
459 a = r->KeyRange.high + 1;
460 }
461 }
462 } else {
463 for (gig::Region* r = instrument->GetFirstRegion() ; ;
464 r = instrument->GetNextRegion()) {
465 if (r != region) {
466 int b = r ? r->KeyRange.low : 128;
467
468 // gap from a to b (not inclusive b)
469
470 if (region->KeyRange.high + k >= b) {
471 // not found the current gap yet, just continue
472 } else {
473
474 if (a > region->KeyRange.low + move.pos) {
475 // this gap is too far to the right, break
476 break;
477 }
478
479 int newlo = std::max(region->KeyRange.low + k, a);
480 int newhigh = newlo + (region->KeyRange.high - region->KeyRange.low);
481
482 if (newhigh < b) {
483 // yes it fits - break as the first one is the best
484 new_k = newlo - region->KeyRange.low;
485 new_touch_left = a > 0 && a == newlo;
486 new_touch_right = b < 128 && newhigh + 1 == b;
487 break;
488 }
489 }
490 if (!r) break;
491 a = r->KeyRange.high + 1;
492 }
493 }
494 }
495 k = new_k;
496 if (k == move.pos) return;
497
498 Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);
499 int prevx = int(w * (move.pos + region->KeyRange.low) / 128.0 + 0.5);
500 x = int(w * (k + region->KeyRange.low) / 128.0 + 0.5);
501 int prevx2 = int(w * (move.pos + region->KeyRange.high + 1) / 128.0 + 0.5);
502 int x2 = int(w * (k + region->KeyRange.high + 1) / 128.0 + 0.5);
503 Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
504 gc->set_foreground(red);
505
506 if (!new_touch_left) window->draw_line(black, x, 1, x, h1 - 2);
507 if (!new_touch_right) window->draw_line(black, x2, 1, x2, h1 - 2);
508
509 if (k > move.pos) {
510 window->draw_rectangle(bg, true, prevx + (move.touch_left ? 1 : 0), 0,
511 std::min(x, prevx2 + 1 - (move.touch_right ? 1 : 0)) -
512 (prevx + (move.touch_left ? 1 : 0)), h1);
513
514 window->draw_line(black, std::max(x, prevx2 + 1), 0, x2, 0);
515 window->draw_line(black, std::max(x, prevx2 + 1), h1 - 1, x2, h1 - 1);
516 window->draw_rectangle(gc, true, std::max(x + 1, prevx2), 1,
517 x2 - std::max(x + 1, prevx2), h1 - 2);
518 } else {
519 window->draw_rectangle(bg, true, std::max(x2 + 1, prevx + (move.touch_left ? 1 : 0)), 0,
520 prevx2 + 1 - (move.touch_right ? 1 : 0) -
521 std::max(x2 + 1, prevx + (move.touch_left ? 1 : 0)), h1);
522
523 window->draw_line(black, x, 0, std::min(x2, prevx - 1), 0);
524 window->draw_line(black, x, h1 - 1, std::min(x2, prevx - 1), h1 - 1);
525
526 window->draw_rectangle(gc, true, x + 1, 1, std::min(x2 - 1, prevx) - x, h1 - 2);
527 }
528
529 move.pos = k;
530 move.touch_left = new_touch_left;
531 move.touch_right = new_touch_right;
532 }
533
534
535 bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)
536 {
537 Glib::RefPtr<Gdk::Window> window = get_window();
538 int x, y;
539 Gdk::ModifierType state = Gdk::ModifierType(0);
540 window->get_pointer(x, y, state);
541
542 if (resize.active) {
543 motion_resize_region(x, y);
544 } else if (move.active) {
545 motion_move_region(x, y);
546 } else {
547 if (is_in_resize_zone(x, y)) {
548 if (!cursor_is_resize) {
549 window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
550 cursor_is_resize = true;
551 }
552 } else if (cursor_is_resize) {
553 window->set_cursor();
554 cursor_is_resize = false;
555 }
556 }
557
558 return true;
559 }
560
561 bool RegionChooser::is_in_resize_zone(double x, double y) {
562 const int w = width - 1;
563
564 if (instrument && y >= 0 && y <= h1) {
565 gig::Region* prev_region = 0;
566 gig::Region* next_region;
567 for (gig::Region* r = instrument->GetFirstRegion() ; r ; r = next_region) {
568 next_region = instrument->GetNextRegion();
569
570 int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);
571 if (x <= lo - 2) break;
572 if (x < lo + 2) {
573 resize.region = r;
574 resize.pos = r->KeyRange.low;
575 resize.max = r->KeyRange.high;
576
577 if (prev_region && prev_region->KeyRange.high + 1 == r->KeyRange.low) {
578 // we don't know yet if it's the high limit of
579 // prev_region or the low limit of r that's going
580 // to be edited
581 resize.mode = resize.undecided;
582 resize.min = prev_region->KeyRange.low + 1;
583 resize.prev_region = prev_region;
584 return true;
585 }
586
587 // edit low limit
588 resize.mode = resize.moving_low_limit;
589 resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;
590 return true;
591 }
592 if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
593 int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);
594 if (x <= hi - 2) break;
595 if (x < hi + 2) {
596 // edit high limit
597 resize.region = r;
598 resize.pos = r->KeyRange.high + 1;
599 resize.mode = resize.moving_high_limit;
600 resize.min = r->KeyRange.low + 1;
601 resize.max = next_region ? next_region->KeyRange.low : 128;
602 return true;
603 }
604 }
605 prev_region = r;
606 }
607 }
608 return false;
609 }
610
611 sigc::signal<void> RegionChooser::signal_region_selected()
612 {
613 return region_selected;
614 }
615
616 sigc::signal<void> RegionChooser::signal_instrument_changed()
617 {
618 return instrument_changed;
619 }
620
621 void RegionChooser::show_region_properties()
622 {
623 if (!region) return;
624 Gtk::Dialog dialog("Region Properties", true /*modal*/);
625 // add "Keygroup" checkbox
626 Gtk::CheckButton checkBoxKeygroup("Member of a Keygroup (Exclusive Group)");
627 checkBoxKeygroup.set_active(region->KeyGroup);
628 dialog.get_vbox()->pack_start(checkBoxKeygroup);
629 checkBoxKeygroup.show();
630 // add "Keygroup" spinbox
631 Gtk::Adjustment adjustment(1, 1, pow(2,32));
632 Gtk::SpinButton spinBox(adjustment);
633 if (region->KeyGroup) spinBox.set_value(region->KeyGroup);
634 dialog.get_vbox()->pack_start(spinBox);
635 spinBox.show();
636 // add OK and CANCEL buttons to the dialog
637 dialog.add_button(Gtk::Stock::OK, 0);
638 dialog.add_button(Gtk::Stock::CANCEL, 1);
639 dialog.show_all_children();
640 if (!dialog.run()) { // OK selected ...
641 region->KeyGroup =
642 (checkBoxKeygroup.get_active()) ? spinBox.get_value_as_int() : 0;
643 }
644 }
645
646 void RegionChooser::add_region()
647 {
648 gig::Region* r;
649 for (r = instrument->GetFirstRegion() ; r ; r = instrument->GetNextRegion()) {
650 if (r->KeyRange.low > new_region_pos) break;
651 }
652
653 region = instrument->AddRegion();
654 region->KeyRange.low = region->KeyRange.high = new_region_pos;
655
656 instrument->MoveRegion(region, r);
657 queue_draw();
658 region_selected();
659 instrument_changed();
660 }
661
662 void RegionChooser::delete_region()
663 {
664 instrument->DeleteRegion(region);
665 region = 0;
666 queue_draw();
667 region_selected();
668 instrument_changed();
669 }
670
671 void RegionChooser::manage_dimensions()
672 {
673 gig::Region* region = get_region();
674 if (!region) return;
675 dimensionManager.show(region);
676 }
677
678 void RegionChooser::on_dimension_manager_changed() {
679 region_selected();
680 instrument_changed();
681 }

  ViewVC Help
Powered by ViewVC