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

Diff of /gigedit/trunk/src/gigedit/regionchooser.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1261 by persson, Thu Jul 5 17:12:20 2007 UTC revision 2695 by schoenebeck, Tue Jan 6 18:11:27 2015 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006, 2007 Andreas Persson   * Copyright (C) 2006-2015 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 18  Line 18 
18   */   */
19    
20  #include "regionchooser.h"  #include "regionchooser.h"
21    
22    #include <algorithm>
23    
24    #include <cairomm/context.h>
25    #include <gdkmm/general.h>
26  #include <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
27  #include <gtkmm/stock.h>  #include <gtkmm/stock.h>
28  #include <gtkmm/spinbutton.h>  #include <gtkmm/spinbutton.h>
29  #include <gtkmm/dialog.h>  #include <gtkmm/dialog.h>
 #include <libintl.h>  
 #include <math.h>  
30    
31  #define _(String) gettext(String)  #include "global.h"
32    
33    #define REGION_BLOCK_HEIGHT             30
34    #define KEYBOARD_HEIGHT                 40
35    
36  RegionChooser::RegionChooser()  void SortedRegions::update(gig::Instrument* instrument) {
37        // Usually, the regions in a gig file are ordered after their key
38        // range, but there are files where they are not. The
39        // RegionChooser code needs a sorted list of regions.
40        regions.clear();
41        if (instrument) {
42            for (gig::Region* r = instrument->GetFirstRegion() ;
43                 r ;
44                 r = instrument->GetNextRegion()) {
45                regions.push_back(r);
46            }
47            sort(regions.begin(), regions.end(), *this);
48        }
49    }
50    
51    gig::Region* SortedRegions::first() {
52        region_iterator = regions.begin();
53        return region_iterator == regions.end() ? 0 : *region_iterator;
54    }
55    
56    gig::Region* SortedRegions::next() {
57        region_iterator++;
58        return region_iterator == regions.end() ? 0 : *region_iterator;
59    }
60    
61    
62    
63    RegionChooser::RegionChooser() :
64        activeKeyColor("red"),
65        red("#8070ff"),
66        grey1("grey69"),
67        white("white"),
68        black("black"),
69        m_VirtKeybModeChoice(_("Virtual Keyboard Mode")),
70        currentActiveKey(-1)
71  {  {
72      Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();      set_size_request(500, KEYBOARD_HEIGHT + REGION_BLOCK_HEIGHT);
73    
     black = Gdk::Color("black");  
     white = Gdk::Color("white");  
     red = Gdk::Color("#8070ff");  
     blue = Gdk::Color("#c098ff");  
     green = Gdk::Color("#a088ff");  
     grey1 = Gdk::Color("red");  
   
     colormap->alloc_color(black);  
     colormap->alloc_color(white);  
     colormap->alloc_color(red);  
     colormap->alloc_color(blue);  
     colormap->alloc_color(green);  
     colormap->alloc_color(grey1);  
74      instrument = 0;      instrument = 0;
75      region = 0;      region = 0;
76      resize.active = false;      resize.active = false;
77        move.active = false;
78      cursor_is_resize = false;      cursor_is_resize = false;
79      h1 = 20;      h1 = REGION_BLOCK_HEIGHT;
80      width = 800;  
81        // properties of the virtual keyboard
82        {
83            const char* choices[] = { _("normal"), _("chord"), 0 };
84            static const virt_keyboard_mode_t values[] = {
85                VIRT_KEYBOARD_MODE_NORMAL,
86                VIRT_KEYBOARD_MODE_CHORD
87            };
88            m_VirtKeybModeChoice.set_choices(choices, values);
89            m_VirtKeybModeChoice.set_value(VIRT_KEYBOARD_MODE_NORMAL);
90        }
91        m_VirtKeybVelocityLabelDescr.set_text(_("Note-On Velocity:"));
92        m_VirtKeybVelocityLabel.set_text("-");
93        m_VirtKeybOffVelocityLabelDescr.set_text(_("Note-Off Velocity:"));
94        m_VirtKeybOffVelocityLabel.set_text("-");
95        m_VirtKeybPropsBox.pack_start(m_VirtKeybModeChoice.label, Gtk::PACK_SHRINK);
96        m_VirtKeybPropsBox.pack_start(m_VirtKeybModeChoice.widget, Gtk::PACK_SHRINK);
97        m_VirtKeybPropsBox.pack_start(m_VirtKeybVelocityLabelDescr, Gtk::PACK_SHRINK);
98        m_VirtKeybPropsBox.pack_start(m_VirtKeybVelocityLabel, Gtk::PACK_SHRINK);
99        m_VirtKeybPropsBox.pack_start(m_VirtKeybOffVelocityLabelDescr, Gtk::PACK_SHRINK);
100        m_VirtKeybPropsBox.pack_start(m_VirtKeybOffVelocityLabel, Gtk::PACK_SHRINK);
101        m_VirtKeybPropsBox.set_spacing(10);
102        m_VirtKeybPropsBox.show();
103        for (int i = 0 ; i < 128 ; i++) key_pressed[i] = false;
104    
105      actionGroup = Gtk::ActionGroup::create();      actionGroup = Gtk::ActionGroup::create();
106      actionGroup->add(Gtk::Action::create("Properties",      actionGroup->add(Gtk::Action::create("Properties",
# Line 86  RegionChooser::RegionChooser() Line 137  RegionChooser::RegionChooser()
137      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
138                 Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK);                 Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK);
139    
140      dimensionManager.articulation_changed_signal.connect(      dimensionManager.region_to_be_changed_signal.connect(
141          sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed)          region_to_be_changed_signal.make_slot()
142        );
143        dimensionManager.region_changed_signal.connect(
144            region_changed_signal.make_slot()
145        );
146        dimensionManager.region_changed_signal.connect(
147            sigc::hide(
148                sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed)
149            )
150        );
151        keyboard_key_hit_signal.connect(
152            sigc::mem_fun(*this, &RegionChooser::on_note_on_event)
153      );      );
154        keyboard_key_released_signal.connect(
155            sigc::mem_fun(*this, &RegionChooser::on_note_off_event)
156        );
157        set_tooltip_text(_("Right click here for adding new region. Use mouse pointer for moving (dragging) or resizing existing regions (by pointing at region's boundary). Right click on an existing region for more actions."));
158  }  }
159    
160  RegionChooser::~RegionChooser()  RegionChooser::~RegionChooser()
161  {  {
162  }  }
163    
164  void RegionChooser::on_realize()  void RegionChooser::invalidate_key(int key) {
165  {      const int h = KEYBOARD_HEIGHT;
166      // We need to call the base on_realize()      const int w = get_width() - 1;
167      Gtk::DrawingArea::on_realize();      int x1 = key_to_x(key - 0.5, w);
168        int x2 = key_to_x(key + 1.5, w);
169    
170        Gdk::Rectangle rect(x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);
171        get_window()->invalidate_rect(rect, false);
172    }
173    
174    void RegionChooser::on_note_on_event(int key, int velocity) {
175        key_pressed[key] = true;
176        invalidate_key(key);
177        m_VirtKeybVelocityLabel.set_text(ToString(velocity));
178    }
179    
180    void RegionChooser::on_note_off_event(int key, int velocity) {
181        key_pressed[key] = false;
182        invalidate_key(key);
183        m_VirtKeybOffVelocityLabel.set_text(ToString(velocity));
184    }
185    
186      // Now we can allocate any additional resources we need  
187      Glib::RefPtr<Gdk::Window> window = get_window();  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
188      gc = Gdk::GC::create(window);  bool RegionChooser::on_expose_event(GdkEventExpose* e) {
189      window->clear();      double clipx1 = e->area.x;
190        double clipx2 = e->area.x + e->area.width;
191        double clipy1 = e->area.y;
192        double clipy2 = e->area.y + e->area.height;
193    
194        const Cairo::RefPtr<Cairo::Context>& cr =
195            get_window()->create_cairo_context();
196    #if 0
197    }
198    #endif
199    #else
200    bool RegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) {
201        double clipx1, clipx2, clipy1, clipy2;
202        cr->get_clip_extents(clipx1, clipy1, clipx2, clipy2);
203    #endif
204    
205        cr->save();
206        cr->set_line_width(1);
207    
208    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
209        const Gdk::Color bg = get_style()->get_bg(Gtk::STATE_NORMAL);
210    #else
211        const Gdk::RGBA bg = get_style_context()->get_background_color();
212    #endif
213        Gdk::Cairo::set_source_rgba(cr, bg);
214        cr->paint();
215    
216        if (clipy2 > h1) {
217            draw_keyboard(cr, clipx1, clipx2);
218        }
219    
220        if (clipy1 < h1 && instrument) {
221            draw_regions(cr, clipx1, clipx2);
222        }
223    
224        cr->restore();
225    
226        return true;
227  }  }
228    
229  bool RegionChooser::on_expose_event(GdkEventExpose* event)  void RegionChooser::draw_keyboard(const Cairo::RefPtr<Cairo::Context>& cr,
230  {                                    int clip_low, int clip_high) {
231      Glib::RefPtr<Gdk::Window> window = get_window();      const int h = KEYBOARD_HEIGHT;
232      window->clear();      const int w = get_width() - 1;
     const int h = 40;  
     const int w = width - 1;  
233      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
234    
235      Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();      Gdk::Cairo::set_source_rgba(cr, black);
236      Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();      cr->rectangle(0.5, h1 + 0.5, w, h - 1);
237        cr->stroke();
238    
239        int x1 = key_to_x(20.5, w);
240        Gdk::Cairo::set_source_rgba(cr, grey1);
241        cr->rectangle(1, h1 + 1, x1 - 1, h - 2);
242        cr->fill();
243    
244        int x2 = key_to_x(109.5, w);
245        Gdk::Cairo::set_source_rgba(cr, white);
246        cr->rectangle(x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);
247        cr->fill();
248    
249        Gdk::Cairo::set_source_rgba(cr, grey1);
250        cr->rectangle(x2 + 1, h1 + 1, w - x2 - 1, h - 2);
251        cr->fill();
252    
253      window->draw_rectangle(black, false, 0, h1, w, h - 1);      Gdk::Cairo::set_source_rgba(cr, black);
     window->draw_rectangle(white, true, 1, h1 + 1, w - 1, h - 2);  
     for (int i = 0 ; i < 128 ; i++) {  
         int note = (i + 3) % 12;  
         int x = int(w * i / 128.0 + 0.5);  
254    
255          if (note == 1 || note == 4 || note == 6 || note == 9 || note == 11) {      int clipkey1 = std::max(0, x_to_key_right(clip_low - 1, w));
256              int x2 = int(w * (i + 0.5) / 128.0 + 0.5);      int clipkey2 = std::min(x_to_key_right(clip_high - 1, w) + 1, 128);
             window->draw_line(black, x2, h1 + bh, x2, h1 + h);  
257    
258              int x3 = int(w * (i + 1) / 128.0 + 0.5);      for (int i = clipkey1 ; i < clipkey2 ; i++) {
259              window->draw_rectangle(black, true, x, h1 + 1, x3 - x + 1, bh);          int note = (i + 3) % 12;
260            int x = key_to_x(i, w);
261    
262            if (note == 1 || note == 4 || note == 6 ||
263                note == 9 || note == 11) {
264                // black key: short line in the middle, with a rectangle
265                // on top
266                int x2 = key_to_x(i + 0.5, w);
267                cr->move_to(x2 + 0.5, h1 + bh + 0.5);
268                cr->line_to(x2 + 0.5, h1 + h - 1);
269                cr->stroke();
270    
271                int x3 = key_to_x(i + 1, w);
272                cr->rectangle(x, h1 + 1, x3 - x + 1, bh);
273                cr->fill();
274          } else if (note == 3 || note == 8) {          } else if (note == 3 || note == 8) {
275              window->draw_line(black, x, h1 + 1, x, h1 + h);              // C or F: long line to the left
276                cr->move_to(x + 0.5, h1 + 1);
277                cr->line_to(x + 0.5, h1 + h - 1);
278                cr->stroke();
279          }          }
280    
281            if (key_pressed[i]) draw_key(cr, i);
282    
283            if (note == 3) draw_digit(cr, i);
284      }      }
285    }
286    
     if (instrument) {  
         int i = 0;  
         gig::Region *nextRegion;  
         int x3 = -1;  
         for (gig::Region *r = instrument->GetFirstRegion() ;  
              r ;  
              r = nextRegion) {  
287    
288              if (x3 < 0) x3 = int(w * (r->KeyRange.low) / 128.0 + 0.5);  void RegionChooser::draw_regions(const Cairo::RefPtr<Cairo::Context>& cr,
289              nextRegion = instrument->GetNextRegion();                                   int clip_low, int clip_high) {
290              if (!nextRegion || r->KeyRange.high + 1 != nextRegion->KeyRange.low) {      const int w = get_width() - 1;
291                  int x2 = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);  
292                  window->draw_line(black, x3, 0, x2, 0);      Gdk::Cairo::set_source_rgba(cr, black);
293                  window->draw_line(black, x3, h1 - 1, x2, h1 - 1);      gig::Region* next_region;
294                  window->draw_line(black, x2, 1, x2, h1 - 2);      int x3 = -1;
295                  window->draw_rectangle(white, true, x3 + 1, 1, x2 - x3 - 1, h1 - 2);      for (gig::Region* r = regions.first() ; r ; r = next_region) {
296                  x3 = -1;          next_region = regions.next();
297    
298            if (x3 < 0) {
299                x3 = key_to_x(r->KeyRange.low, w);
300                if (x3 >= clip_high) break;
301            }
302            if (!next_region ||
303                r->KeyRange.high + 1 != next_region->KeyRange.low ||
304                r == region || next_region == region) {
305    
306                int x2 = key_to_x(r->KeyRange.high + 1, w);
307                if (x2 >= clip_low) {
308                    cr->move_to(x3, 0.5);
309                    cr->line_to(x2 + 0.5, 0.5);
310                    cr->line_to(x2 + 0.5, h1 - 0.5);
311                    cr->line_to(x3, h1 - 0.5);
312                    cr->stroke();
313    
314                    Gdk::Cairo::set_source_rgba(cr, region == r ? red : white);
315                    cr->rectangle(x3 + 1, 1, x2 - x3 - 1, h1 - 2);
316                    cr->fill();
317                    Gdk::Cairo::set_source_rgba(cr, black);
318              }              }
319              i++;              x3 = -1;
320          }          }
321        }
322    
323          for (gig::Region *r = instrument->GetFirstRegion() ;      for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
324               r ;          int x = key_to_x(r->KeyRange.low, w);
              r = instrument->GetNextRegion()) {  
             int x = int(w * (r->KeyRange.low) / 128.0 + 0.5);  
             window->draw_line(black, x, 1, x, h1 - 2);  
         }  
325    
326          if (region) {          if (x < clip_low) continue;
327              int x1 = int(w * (region->KeyRange.low) / 128.0 + 0.5);          if (x >= clip_high) break;
             int x2 = int(w * (region->KeyRange.high + 1) / 128.0 + 0.5);  
             gc->set_foreground(red);  
             window->draw_rectangle(gc, true, x1 + 1, 1, x2 - x1 - 1, h1 - 2);  
         }  
     }  
     return true;  
 }  
328    
329            cr->move_to(x + 0.5, 1);
330            cr->line_to(x + 0.5, h1 - 1);
331            cr->stroke();
332        }
333    
334  void RegionChooser::on_size_request(GtkRequisition* requisition)      // if there is no region yet, show the user some hint text that he may
335  {      // right click on this area to create a new region
336      *requisition = GtkRequisition();      if (!regions.first()) {
337      requisition->height = 40 + 20;          Glib::RefPtr<Pango::Context> context = get_pango_context();
338      requisition->width = 500;          Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
339            layout->set_alignment(Pango::ALIGN_CENTER);
340            layout->set_text(Glib::ustring("*** ") + _("Right click here to create a region.") + " ***");
341            layout->set_width(get_width() * Pango::SCALE);
342            //layout->set_height(get_height() * Pango::SCALE);
343            layout->set_spacing(10);
344            Gdk::Cairo::set_source_rgba(cr, red);        
345            // get the text dimensions
346            Pango::Rectangle rect = layout->get_logical_extents();
347            int text_width, text_height;
348            layout->get_pixel_size(text_width, text_height);
349            cr->move_to(0, (REGION_BLOCK_HEIGHT - text_height) / 2);
350    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
351            pango_cairo_show_layout(cr->cobj(), layout->gobj());
352    #else
353            layout->show_in_cairo_context(cr);
354    #endif
355        }
356  }  }
357    
358    bool RegionChooser::is_black_key(int key) {
359  // not used      const int note = (key + 3) % 12;
360  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)      return note == 1 || note == 4 || note == 6 || note == 9 || note == 11;
361  {  }
362      const int h = 40;  
363      const int w = width;  void RegionChooser::draw_digit(const Cairo::RefPtr<Cairo::Context>& cr,
364                                   int key) {
365        const int h = KEYBOARD_HEIGHT;
366        const int w = get_width() - 1;
367        Glib::RefPtr<Pango::Layout> layout =
368            Pango::Layout::create(get_pango_context());
369        char buf[30];
370        sprintf(buf, "<span size=\"8000\">%d</span>", key / 12 - 1);
371        layout->set_markup(buf);
372        Pango::Rectangle rectangle = layout->get_logical_extents();
373        double text_w = double(rectangle.get_width()) / Pango::SCALE;
374        double text_h = double(rectangle.get_height()) / Pango::SCALE;
375        double x = w * (key + 0.75) / 128.0;
376        Gdk::Cairo::set_source_rgba(cr, black);
377        cr->move_to(int(x - text_w / 2 + 1), int(h1 + h - text_h + 0.5));
378    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
379        pango_cairo_show_layout(cr->cobj(), layout->gobj());
380    #else
381        layout->show_in_cairo_context(cr);
382    #endif
383    }
384    
385    void RegionChooser::draw_key(const Cairo::RefPtr<Cairo::Context>& cr,
386                                 int key) {
387        const int h = KEYBOARD_HEIGHT;
388        const int w = get_width() - 1;
389      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
390    
391      Glib::RefPtr<Gdk::Window> window = get_window();      Gdk::Cairo::set_source_rgba(cr, activeKeyColor);
     gc->set_foreground(color);  
392    
393      for (int i = from ; i < to ; i++) {      int note = (key + 3) % 12;
394          int note = (i + 3) % 12;      int x = key_to_x(key, w) + 1;
395          int x = int(w * i / 128.0 + 0.5) + 1;      int x2 = key_to_x(key + 1.5, w);
396          int x2 = int(w * (i + 1.5) / 128.0 + 0.5);      int x3 = key_to_x(key + 1, w);
397          int x3 = int(w * (i + 1) / 128.0 + 0.5);      int x4 = key_to_x(key - 0.5, w);
398          int x4 = int(w * (i - 0.5) / 128 + 0.5) + 1;      int w1 = x3 - x;
399          int w1 = x3 - x;      switch (note) {
400          switch (note) {      case 0: case 5: case 10:
401          case 0: case 5: case 10:          cr->rectangle(x, h1 + 1, w1, bh);
402              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);          cr->fill();
403              window->draw_rectangle(gc, true, x4, h1 + bh + 1, x2 - x4, h - bh - 2);          cr->rectangle(x4 + 1, h1 + bh + 1, x2 - x4 - 1, h - bh - 2);
404              break;          cr->fill();
405          case 2: case 7:          break;
406              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);      case 2: case 7:
407              window->draw_rectangle(gc, true, x4, h1 + bh + 1, x3 - x4, h - bh - 2);          cr->rectangle(x, h1 + 1, w1, bh);
408              break;          cr->fill();
409          case 3: case 8:          cr->rectangle(x4 + 1, h1 + bh + 1, x3 - x4 - 1, h - bh - 2);
410              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);          cr->fill();
411              window->draw_rectangle(gc, true, x, h1 + bh + 1, x2 - x, h - bh - 2);          break;
412              break;      case 3: case 8:
413          default:          cr->rectangle(x, h1 + 1, w1, bh);
414              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh - 1);          cr->fill();
415              break;          cr->rectangle(x, h1 + bh + 1, x2 - x, h - bh - 2);
416          }          cr->fill();
417            break;
418        default:
419            cr->rectangle(x, h1 + 1, w1, bh - 1);
420            cr->fill();
421            break;
422      }      }
423        Gdk::Cairo::set_source_rgba(cr, black);
424  }  }
425    
426  void RegionChooser::set_instrument(gig::Instrument* instrument)  void RegionChooser::set_instrument(gig::Instrument* instrument)
427  {  {
428      this->instrument = instrument;      this->instrument = instrument;
429      region = instrument ? instrument->GetFirstRegion() : 0;      regions.update(instrument);
430        region = regions.first();
431      queue_draw();      queue_draw();
432      region_selected();      region_selected();
433        dimensionManager.set_region(region);
434  }  }
435    
436  bool RegionChooser::on_button_release_event(GdkEventButton* event)  bool RegionChooser::on_button_release_event(GdkEventButton* event)
437  {  {
438        const int k = x_to_key(event->x, get_width() - 1);
439    
440        // handle-note off on virtual keyboard
441        if (event->type == GDK_BUTTON_RELEASE) {
442            int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
443                           int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
444            if (velocity <= 0) velocity = 1;
445            switch (m_VirtKeybModeChoice.get_value()) {
446                case VIRT_KEYBOARD_MODE_CHORD:
447                    if (event->y >= REGION_BLOCK_HEIGHT)
448                        keyboard_key_released_signal.emit(k, velocity);
449                    break;
450                case VIRT_KEYBOARD_MODE_NORMAL:
451                default:
452                    if (currentActiveKey >= 0 && currentActiveKey <= 127) {
453                        keyboard_key_released_signal.emit(currentActiveKey, velocity);
454                        currentActiveKey = -1;
455                    }
456                    break;
457            }
458        }
459    
460      if (resize.active) {      if (resize.active) {
461    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
462          get_window()->pointer_ungrab(event->time);          get_window()->pointer_ungrab(event->time);
463    #else
464            Glib::wrap(event->device, true)->ungrab(event->time);
465    #endif
466          resize.active = false;          resize.active = false;
467    
         if (resize.mode == resize.moving_high_limit) {  
             if (resize.region->KeyRange.high != resize.pos - 1) {  
                 resize.region->KeyRange.high = resize.pos - 1;  
                 instrument_changed();  
             }  
         } else if (resize.mode == resize.moving_low_limit) {  
             if (resize.region->KeyRange.low != resize.pos) {  
                 resize.region->KeyRange.low = resize.pos;  
                 instrument_changed();  
             }  
         }  
   
468          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
469              get_window()->set_cursor();              get_window()->set_cursor();
470              cursor_is_resize = false;              cursor_is_resize = false;
471          }          }
472        } else if (move.active) {
473    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
474            get_window()->pointer_ungrab(event->time);
475    #else
476            Glib::wrap(event->device, true)->ungrab(event->time);
477    #endif
478            move.active = false;
479    
480            if (is_in_resize_zone(event->x, event->y)) {
481    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
482                get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
483    #else
484                get_window()->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
485    #endif
486                cursor_is_resize = true;
487            }
488      }      }
489      return true;      return true;
490  }  }
491    
492    void RegionChooser::update_after_resize()
493    {
494        if (resize.mode == resize.moving_high_limit) {
495            if (resize.region->KeyRange.high != resize.pos - 1) {
496                instrument_struct_to_be_changed_signal.emit(instrument);
497                resize.region->SetKeyRange(resize.region->KeyRange.low,
498                                           resize.pos - 1);
499                regions.update(instrument);
500                instrument_changed.emit();
501                instrument_struct_changed_signal.emit(instrument);
502            }
503        } else if (resize.mode == resize.moving_low_limit) {
504            if (resize.region->KeyRange.low != resize.pos) {
505                instrument_struct_to_be_changed_signal.emit(instrument);
506                resize.region->SetKeyRange(resize.pos,
507                                           resize.region->KeyRange.high);
508                regions.update(instrument);
509                instrument_changed.emit();
510                instrument_struct_changed_signal.emit(instrument);
511            }
512        }
513    }
514    
515    void RegionChooser::update_after_move(int pos)
516    {
517        instrument_struct_to_be_changed_signal.emit(instrument);
518        region->SetKeyRange(pos, pos + region->KeyRange.high -
519                            region->KeyRange.low);
520        regions.update(instrument);
521        instrument_changed.emit();
522        instrument_struct_changed_signal.emit(instrument);
523    }
524    
525  bool RegionChooser::on_button_press_event(GdkEventButton* event)  bool RegionChooser::on_button_press_event(GdkEventButton* event)
526  {  {
527      if (!instrument) return true;      if (!instrument) return true;
528    
529      int k = int(event->x / (width - 1) * 128.0);      const int w = get_width() - 1;
530        const int k = x_to_key(event->x, w);
531    
532        if (event->type == GDK_BUTTON_PRESS) {
533            if (event->y >= REGION_BLOCK_HEIGHT) {
534                int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
535                               int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
536                currentActiveKey = k;
537                keyboard_key_hit_signal.emit(k, velocity);
538            }
539        }
540    
541        // left mouse button double click
542        if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
543            if (event->y < REGION_BLOCK_HEIGHT) {
544                // show dimension manager dialog for this region
545                manage_dimensions();
546            }
547        }
548    
549        if (event->y >= REGION_BLOCK_HEIGHT) return true;
550      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
551          gig::Region* r = get_region(k);          gig::Region* r = get_region(k);
552          if (r) {          if (r) {
553              region = r;              region = r;
554              queue_draw();              queue_draw();
555              region_selected();              region_selected();
556                dimensionManager.set_region(region);
557              popup_menu_inside_region->popup(event->button, event->time);              popup_menu_inside_region->popup(event->button, event->time);
558          } else {          } else {
559              new_region_pos = k;              new_region_pos = k;
# Line 271  bool RegionChooser::on_button_press_even Line 561  bool RegionChooser::on_button_press_even
561          }          }
562      } else {      } else {
563          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
564              Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
565              get_window()->pointer_grab(false,              get_window()->pointer_grab(false,
566                                         Gdk::BUTTON_RELEASE_MASK |                                         Gdk::BUTTON_RELEASE_MASK |
567                                         Gdk::POINTER_MOTION_MASK |                                         Gdk::POINTER_MOTION_MASK |
568                                         Gdk::POINTER_MOTION_HINT_MASK,                                         Gdk::POINTER_MOTION_HINT_MASK,
569                                         double_arrow, event->time);                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW),
570                                           event->time);
571    #else
572                Glib::wrap(event->device, true)->grab(get_window(),
573                                                      Gdk::OWNERSHIP_NONE,
574                                                      false,
575                                                      Gdk::BUTTON_RELEASE_MASK |
576                                                      Gdk::POINTER_MOTION_MASK |
577                                                      Gdk::POINTER_MOTION_HINT_MASK,
578                                                      Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW),
579                                                      event->time);
580    #endif
581              resize.active = true;              resize.active = true;
582          } else {          } else {
583              gig::Region* r = get_region(k);              gig::Region* r = get_region(k);
# Line 284  bool RegionChooser::on_button_press_even Line 585  bool RegionChooser::on_button_press_even
585                  region = r;                  region = r;
586                  queue_draw();                  queue_draw();
587                  region_selected();                  region_selected();
588                    dimensionManager.set_region(region);
589    
590    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
591                    get_window()->pointer_grab(false,
592                                               Gdk::BUTTON_RELEASE_MASK |
593                                               Gdk::POINTER_MOTION_MASK |
594                                               Gdk::POINTER_MOTION_HINT_MASK,
595                                               Gdk::Cursor(Gdk::FLEUR),
596                                               event->time);
597    #else
598                    Glib::wrap(event->device, true)->grab(get_window(),
599                                                          Gdk::OWNERSHIP_NONE,
600                                                          false,
601                                                          Gdk::BUTTON_RELEASE_MASK |
602                                                          Gdk::POINTER_MOTION_MASK |
603                                                          Gdk::POINTER_MOTION_HINT_MASK,
604                                                          Gdk::Cursor::create(Gdk::FLEUR),
605                                                          event->time);
606    #endif
607                    move.active = true;
608                    move.offset = event->x - key_to_x(region->KeyRange.low, w);
609              }              }
610          }          }
611      }      }
# Line 292  bool RegionChooser::on_button_press_even Line 614  bool RegionChooser::on_button_press_even
614    
615  gig::Region* RegionChooser::get_region(int key)  gig::Region* RegionChooser::get_region(int key)
616  {  {
617      for (gig::Region *r = instrument->GetFirstRegion() ; r ;      for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
          r = instrument->GetNextRegion()) {  
618          if (key < r->KeyRange.low) return 0;          if (key < r->KeyRange.low) return 0;
619          if (key <= r->KeyRange.high) return r;          if (key <= r->KeyRange.high) return r;
620      }      }
621      return 0;      return 0;
622  }  }
623    
624  bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)  void RegionChooser::set_region(gig::Region* region) {
625        this->region = region;
626        queue_draw();
627        region_selected();
628        dimensionManager.set_region(region);
629    }
630    
631    void RegionChooser::motion_resize_region(int x, int y)
632  {  {
633      const int w = width - 1;      const int w = get_width() - 1;
     Glib::RefPtr<Gdk::Window> window = get_window();  
     int x, y;  
     Gdk::ModifierType state = Gdk::ModifierType(0);  
     window->get_pointer(x, y, state);  
     if (resize.active) {  
         int k = int(double(x) / w * 128.0 + 0.5);  
634    
635          if (k < resize.min) k = resize.min;      int k = int(double(x) / w * 128.0 + 0.5);
         else if (k > resize.max) k = resize.max;  
636    
637          if (k != resize.pos) {      if (k < resize.min) k = resize.min;
638              if (resize.mode == resize.undecided) {      else if (k > resize.max) k = resize.max;
639                  if (k < resize.pos) {  
640                      // edit high limit of prev_region      if (k != resize.pos) {
641                      resize.max = resize.region->KeyRange.low;          if (resize.mode == resize.undecided) {
642                      resize.region = resize.prev_region;              if (k < resize.pos) {
643                      resize.mode = resize.moving_high_limit;                  // edit high limit of prev_region
644                  } else {                  resize.max = resize.region->KeyRange.low;
645                      // edit low limit of region                  resize.region = resize.prev_region;
646                      resize.min = resize.prev_region->KeyRange.high + 1;                  resize.mode = resize.moving_high_limit;
647                      resize.mode = resize.moving_low_limit;              } else {
648                  }                  // edit low limit of region
649                    resize.min = resize.prev_region->KeyRange.high + 1;
650                    resize.mode = resize.moving_low_limit;
651                }
652            }
653            resize.pos = k;
654    
655            int x1, x2;
656            if (resize.mode == resize.moving_high_limit) {
657                if (resize.region->KeyRange.high < resize.pos - 1) {
658                    x1 = resize.region->KeyRange.high;
659                    x2 = resize.pos - 1;
660                } else {
661                    x1 = resize.pos - 1;
662                    x2 = resize.region->KeyRange.high;
663              }              }
664              Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();          } else {
665              Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();              if (resize.region->KeyRange.low < resize.pos) {
666              if (region == resize.region) {                  x1 = resize.region->KeyRange.low;
667                  gc->set_foreground(red);                  x2 = resize.pos;
668                  white = gc;              } else {
669                    x1 = resize.pos;
670                    x2 = resize.region->KeyRange.low;
671              }              }
672              Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);          }
673              int prevx = int(w * resize.pos / 128.0 + 0.5);          x1 = key_to_x(x1, w);
674              x = int(w * k / 128.0 + 0.5);          x2 = key_to_x(x2 + 1, w) + 1;
675            Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
676              if (resize.mode == resize.moving_high_limit) {  
677                  if (k > resize.pos) {          update_after_resize();
678                      window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);  
679                      window->draw_line(black, prevx, 0, x, 0);          get_window()->invalidate_rect(rect, false);
680                      window->draw_line(black, prevx, h1 - 1, x, h1 - 1);      }
681    }
682    
683    void RegionChooser::motion_move_region(int x, int y)
684    {
685        const int w = get_width() - 1;
686    
687        int l = int(double(x - move.offset) / w * 128.0 + 0.5);
688    
689        if (l == region->KeyRange.low) return;
690        int new_l;
691        int regionsize = region->KeyRange.high - region->KeyRange.low;
692        int a = 0;
693        if (l > region->KeyRange.low) {
694            for (gig::Region* r = regions.first() ; ; r = regions.next()) {
695                if (r != region) {
696                    int b = r ? r->KeyRange.low : 128;
697    
698                    // gap: from a to b (not inclusive b)
699    
700                    if (region->KeyRange.high >= b) {
701                        // not found the current gap yet, just continue
702                  } else {                  } else {
703                      int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);  
704                      window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);                      if (a > l) {
705                            // this gap is too far to the right, break
706                            break;
707                        }
708    
709                        int newhigh = std::min(l + regionsize, b - 1);
710                        int newlo = newhigh - regionsize;
711    
712                        if (newlo >= a) {
713                            // yes it fits - it's a candidate
714                            new_l = newlo;
715                        }
716                  }                  }
717              } else {                  if (!r) break;
718                  if (k < resize.pos) {                  a = r->KeyRange.high + 1;
719                      window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);              }
720                      window->draw_line(black, x, 0, prevx, 0);          }
721                      window->draw_line(black, x, h1 - 1, prevx, h1 - 1);      } else {
722            for (gig::Region* r = regions.first() ; ; r = regions.next()) {
723                if (r != region) {
724                    int b = r ? r->KeyRange.low : 128;
725    
726                    // gap from a to b (not inclusive b)
727    
728                    if (l + regionsize >= b) {
729                        // not found the current gap yet, just continue
730                  } else {                  } else {
731                      int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);  
732                      window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);                      if (a > region->KeyRange.low) {
733                            // this gap is too far to the right, break
734                            break;
735                        }
736    
737                        int newlo = std::max(l, a);
738                        int newhigh = newlo + regionsize;
739    
740                        if (newhigh < b) {
741                            // yes it fits - break as the first one is the best
742                            new_l = newlo;
743                            break;
744                        }
745                  }                  }
746                    if (!r) break;
747                    a = r->KeyRange.high + 1;
748              }              }
             window->draw_line(black, x, 1, x, h1 - 2);  
             resize.pos = k;  
749          }          }
750        }
751        if (new_l == region->KeyRange.low) return;
752    
753        int x1 = key_to_x(std::min(int(region->KeyRange.low), new_l), w);
754        int x2 = key_to_x(std::max(int(region->KeyRange.high),
755                                   new_l + regionsize) + 1, w) + 1;
756    
757        Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
758        update_after_move(new_l);
759    
760        get_window()->invalidate_rect(rect, false);
761    }
762    
763    
764    bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)
765    {
766        Glib::RefPtr<Gdk::Window> window = get_window();
767        int x, y;
768        Gdk::ModifierType state = Gdk::ModifierType(0);
769        window->get_pointer(x, y, state);
770    
771        // handle virtual MIDI keyboard
772        if (m_VirtKeybModeChoice.get_value() != VIRT_KEYBOARD_MODE_CHORD &&
773            currentActiveKey > 0 &&
774            event->y >= REGION_BLOCK_HEIGHT &&
775            event->y < REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT)
776        {
777            const int k = x_to_key(event->x, get_width() - 1);
778            if (k != currentActiveKey) {
779                int velocity =
780                    (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
781                    int(float(event->y - REGION_BLOCK_HEIGHT) /
782                        float(KEYBOARD_HEIGHT) * 128.0f) + 1;
783                if (velocity <= 0) velocity = 1;
784                keyboard_key_released_signal.emit(currentActiveKey, velocity);
785                currentActiveKey = k;
786                keyboard_key_hit_signal.emit(k, velocity);
787            }
788        }
789    
790        if (resize.active) {
791            motion_resize_region(x, y);
792        } else if (move.active) {
793            motion_move_region(x, y);
794      } else {      } else {
795          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
796              if (!cursor_is_resize) {              if (!cursor_is_resize) {
797                  Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
798                  window->set_cursor(double_arrow);                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
799    #else
800                    window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
801    #endif
802                  cursor_is_resize = true;                  cursor_is_resize = true;
803              }              }
804          } else if (cursor_is_resize) {          } else if (cursor_is_resize) {
# Line 375  bool RegionChooser::on_motion_notify_eve Line 811  bool RegionChooser::on_motion_notify_eve
811  }  }
812    
813  bool RegionChooser::is_in_resize_zone(double x, double y) {  bool RegionChooser::is_in_resize_zone(double x, double y) {
814      const int w = width - 1;      const int w = get_width() - 1;
815    
816      if (instrument && y >= 0 && y <= h1) {      if (instrument && y >= 0 && y <= h1) {
817          gig::Region* prev_region = 0;          gig::Region* prev_region = 0;
818          gig::Region* next_region;          gig::Region* next_region;
819          for (gig::Region* r = instrument->GetFirstRegion() ; r ; r = next_region) {          for (gig::Region* r = regions.first(); r ; r = next_region) {
820              next_region = instrument->GetNextRegion();              next_region = regions.next();
821    
822              int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);              int lo = key_to_x(r->KeyRange.low, w);
823              if (x <= lo - 2) break;              if (x <= lo - 2) break;
824              if (x < lo + 2) {              if (x < lo + 2) {
825                  resize.region = r;                  resize.region = r;
# Line 397  bool RegionChooser::is_in_resize_zone(do Line 833  bool RegionChooser::is_in_resize_zone(do
833                      resize.mode = resize.undecided;                      resize.mode = resize.undecided;
834                      resize.min = prev_region->KeyRange.low + 1;                      resize.min = prev_region->KeyRange.low + 1;
835                      resize.prev_region = prev_region;                      resize.prev_region = prev_region;
836                      return true;                      return resize.min != resize.max;
837                  }                  }
838    
839                  // edit low limit                  // edit low limit
840                  resize.mode = resize.moving_low_limit;                  resize.mode = resize.moving_low_limit;
841                  resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;                  resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;
842                  return true;                  return resize.min != resize.max;
843              }              }
844              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
845                  int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);                  int hi = key_to_x(r->KeyRange.high + 1, w);
846                  if (x <= hi - 2) break;                  if (x <= hi - 2) break;
847                  if (x < hi + 2) {                  if (x < hi + 2) {
848                      // edit high limit                      // edit high limit
# Line 415  bool RegionChooser::is_in_resize_zone(do Line 851  bool RegionChooser::is_in_resize_zone(do
851                      resize.mode = resize.moving_high_limit;                      resize.mode = resize.moving_high_limit;
852                      resize.min = r->KeyRange.low + 1;                      resize.min = r->KeyRange.low + 1;
853                      resize.max = next_region ? next_region->KeyRange.low : 128;                      resize.max = next_region ? next_region->KeyRange.low : 128;
854                      return true;                      return resize.min != resize.max;
855                  }                  }
856              }              }
857              prev_region = r;              prev_region = r;
# Line 424  bool RegionChooser::is_in_resize_zone(do Line 860  bool RegionChooser::is_in_resize_zone(do
860      return false;      return false;
861  }  }
862    
863  sigc::signal<void> RegionChooser::signal_region_selected()  sigc::signal<void>& RegionChooser::signal_region_selected()
864  {  {
865      return region_selected;      return region_selected;
866  }  }
867    
868  sigc::signal<void> RegionChooser::signal_instrument_changed()  sigc::signal<void>& RegionChooser::signal_instrument_changed()
869  {  {
870      return instrument_changed;      return instrument_changed;
871  }  }
# Line 437  sigc::signal<void> RegionChooser::signal Line 873  sigc::signal<void> RegionChooser::signal
873  void RegionChooser::show_region_properties()  void RegionChooser::show_region_properties()
874  {  {
875      if (!region) return;      if (!region) return;
876      Gtk::Dialog dialog("Region Properties", true /*modal*/);      Gtk::Dialog dialog(_("Region Properties"), true /*modal*/);
877      // add "Keygroup" checkbox      // add "Keygroup" checkbox
878      Gtk::CheckButton checkBoxKeygroup("Member of a Keygroup (Exclusive Group)");      Gtk::CheckButton checkBoxKeygroup(_("Member of a Keygroup (Exclusive Group)"));
879      checkBoxKeygroup.set_active(region->KeyGroup);      checkBoxKeygroup.set_active(region->KeyGroup);
880      dialog.get_vbox()->pack_start(checkBoxKeygroup);      dialog.get_vbox()->pack_start(checkBoxKeygroup);
881      checkBoxKeygroup.show();      checkBoxKeygroup.show();
882      // add "Keygroup" spinbox      // add "Keygroup" spinbox
883      Gtk::Adjustment adjustment(1, 1, pow(2,32));  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
884        Gtk::Adjustment adjustment(1, 1, 999);
885      Gtk::SpinButton spinBox(adjustment);      Gtk::SpinButton spinBox(adjustment);
886    #else
887        Gtk::SpinButton spinBox(Gtk::Adjustment::create(1, 1, 999));
888    #endif
889      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);
890      dialog.get_vbox()->pack_start(spinBox);      dialog.get_vbox()->pack_start(spinBox);
891      spinBox.show();      spinBox.show();
# Line 461  void RegionChooser::show_region_properti Line 901  void RegionChooser::show_region_properti
901    
902  void RegionChooser::add_region()  void RegionChooser::add_region()
903  {  {
904      gig::Region* r;      instrument_struct_to_be_changed_signal.emit(instrument);
     for (r = instrument->GetFirstRegion() ; r ; r = instrument->GetNextRegion()) {  
         if (r->KeyRange.low > new_region_pos) break;  
     }  
905    
906      region = instrument->AddRegion();      region = instrument->AddRegion();
907      region->KeyRange.low = region->KeyRange.high = new_region_pos;      region->SetKeyRange(new_region_pos, new_region_pos);
908    
909        instrument_struct_changed_signal.emit(instrument);
910        regions.update(instrument);
911    
     instrument->MoveRegion(region, r);  
912      queue_draw();      queue_draw();
913      region_selected();      region_selected();
914        dimensionManager.set_region(region);
915      instrument_changed();      instrument_changed();
916  }  }
917    
918  void RegionChooser::delete_region()  void RegionChooser::delete_region()
919  {  {
920        instrument_struct_to_be_changed_signal.emit(instrument);
921      instrument->DeleteRegion(region);      instrument->DeleteRegion(region);
922        instrument_struct_changed_signal.emit(instrument);
923        regions.update(instrument);
924    
925      region = 0;      region = 0;
926      queue_draw();      queue_draw();
927      region_selected();      region_selected();
928        dimensionManager.set_region(region);
929      instrument_changed();      instrument_changed();
930  }  }
931    
# Line 495  void RegionChooser::on_dimension_manager Line 940  void RegionChooser::on_dimension_manager
940      region_selected();      region_selected();
941      instrument_changed();      instrument_changed();
942  }  }
943    
944    sigc::signal<void, gig::Instrument*>& RegionChooser::signal_instrument_struct_to_be_changed() {
945        return instrument_struct_to_be_changed_signal;
946    }
947    
948    sigc::signal<void, gig::Instrument*>& RegionChooser::signal_instrument_struct_changed() {
949        return instrument_struct_changed_signal;
950    }
951    
952    sigc::signal<void, gig::Region*>& RegionChooser::signal_region_to_be_changed() {
953        return region_to_be_changed_signal;
954    }
955    
956    sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {
957        return region_changed_signal;
958    }
959    
960    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_hit() {
961        return keyboard_key_hit_signal;
962    }
963    
964    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_released() {
965        return keyboard_key_released_signal;
966    }

Legend:
Removed from v.1261  
changed lines
  Added in v.2695

  ViewVC Help
Powered by ViewVC