/[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 1411 - (show annotations) (download)
Fri Oct 12 17:46:29 2007 UTC (16 years, 5 months ago) by schoenebeck
File size: 25127 byte(s)
* added status bar to the bottom of main window (independent area on the
  right shows whether gigedit is running stand-alone or attached to
  LinuxSampler)
* minor cosmetical fix in dimension manager widget
* regionchooser.cpp: temporary fix for a crash which occured when gigedit
  was compiled with CXXFLAGS="-g"

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

  ViewVC Help
Powered by ViewVC