/[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 2536 by schoenebeck, Mon Apr 21 17:49:17 2014 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006, 2007 Andreas Persson   * Copyright (C) 2006-2014 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             20
34    #define KEYBOARD_HEIGHT                 40
35    
36    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  RegionChooser::RegionChooser()  
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);
254      window->draw_rectangle(white, true, 1, h1 + 1, w - 1, h - 2);  
255      for (int i = 0 ; i < 128 ; i++) {      int clipkey1 = std::max(0, x_to_key_right(clip_low - 1, w));
256          int note = (i + 3) % 12;      int clipkey2 = std::min(x_to_key_right(clip_high - 1, w) + 1, 128);
         int x = int(w * i / 128.0 + 0.5);  
257    
258          if (note == 1 || note == 4 || note == 6 || note == 9 || note == 11) {      for (int i = clipkey1 ; i < clipkey2 ; i++) {
259              int x2 = int(w * (i + 0.5) / 128.0 + 0.5);          int note = (i + 3) % 12;
260              window->draw_line(black, x2, h1 + bh, x2, h1 + h);          int x = key_to_x(i, w);
261    
262              int x3 = int(w * (i + 1) / 128.0 + 0.5);          if (note == 1 || note == 4 || note == 6 ||
263              window->draw_rectangle(black, true, x, h1 + 1, x3 - x + 1, bh);              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            Gdk::Cairo::set_source_rgba(cr, red);
343    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
344            pango_cairo_show_layout(cr->cobj(), layout->gobj());
345    #else
346            layout->show_in_cairo_context(cr);
347    #endif
348        }
349  }  }
350    
351    bool RegionChooser::is_black_key(int key) {
352  // not used      const int note = (key + 3) % 12;
353  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)      return note == 1 || note == 4 || note == 6 || note == 9 || note == 11;
354  {  }
355      const int h = 40;  
356      const int w = width;  void RegionChooser::draw_digit(const Cairo::RefPtr<Cairo::Context>& cr,
357                                   int key) {
358        const int h = KEYBOARD_HEIGHT;
359        const int w = get_width() - 1;
360        Glib::RefPtr<Pango::Layout> layout =
361            Pango::Layout::create(get_pango_context());
362        char buf[30];
363        sprintf(buf, "<span size=\"8000\">%d</span>", key / 12 - 1);
364        layout->set_markup(buf);
365        Pango::Rectangle rectangle = layout->get_logical_extents();
366        double text_w = double(rectangle.get_width()) / Pango::SCALE;
367        double text_h = double(rectangle.get_height()) / Pango::SCALE;
368        double x = w * (key + 0.75) / 128.0;
369        Gdk::Cairo::set_source_rgba(cr, black);
370        cr->move_to(int(x - text_w / 2 + 1), int(h1 + h - text_h + 0.5));
371    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
372        pango_cairo_show_layout(cr->cobj(), layout->gobj());
373    #else
374        layout->show_in_cairo_context(cr);
375    #endif
376    }
377    
378    void RegionChooser::draw_key(const Cairo::RefPtr<Cairo::Context>& cr,
379                                 int key) {
380        const int h = KEYBOARD_HEIGHT;
381        const int w = get_width() - 1;
382      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
383    
384      Glib::RefPtr<Gdk::Window> window = get_window();      Gdk::Cairo::set_source_rgba(cr, activeKeyColor);
     gc->set_foreground(color);  
385    
386      for (int i = from ; i < to ; i++) {      int note = (key + 3) % 12;
387          int note = (i + 3) % 12;      int x = key_to_x(key, w) + 1;
388          int x = int(w * i / 128.0 + 0.5) + 1;      int x2 = key_to_x(key + 1.5, w);
389          int x2 = int(w * (i + 1.5) / 128.0 + 0.5);      int x3 = key_to_x(key + 1, w);
390          int x3 = int(w * (i + 1) / 128.0 + 0.5);      int x4 = key_to_x(key - 0.5, w);
391          int x4 = int(w * (i - 0.5) / 128 + 0.5) + 1;      int w1 = x3 - x;
392          int w1 = x3 - x;      switch (note) {
393          switch (note) {      case 0: case 5: case 10:
394          case 0: case 5: case 10:          cr->rectangle(x, h1 + 1, w1, bh);
395              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);          cr->fill();
396              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);
397              break;          cr->fill();
398          case 2: case 7:          break;
399              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);      case 2: case 7:
400              window->draw_rectangle(gc, true, x4, h1 + bh + 1, x3 - x4, h - bh - 2);          cr->rectangle(x, h1 + 1, w1, bh);
401              break;          cr->fill();
402          case 3: case 8:          cr->rectangle(x4 + 1, h1 + bh + 1, x3 - x4 - 1, h - bh - 2);
403              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);          cr->fill();
404              window->draw_rectangle(gc, true, x, h1 + bh + 1, x2 - x, h - bh - 2);          break;
405              break;      case 3: case 8:
406          default:          cr->rectangle(x, h1 + 1, w1, bh);
407              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh - 1);          cr->fill();
408              break;          cr->rectangle(x, h1 + bh + 1, x2 - x, h - bh - 2);
409          }          cr->fill();
410            break;
411        default:
412            cr->rectangle(x, h1 + 1, w1, bh - 1);
413            cr->fill();
414            break;
415      }      }
416        Gdk::Cairo::set_source_rgba(cr, black);
417  }  }
418    
419  void RegionChooser::set_instrument(gig::Instrument* instrument)  void RegionChooser::set_instrument(gig::Instrument* instrument)
420  {  {
421      this->instrument = instrument;      this->instrument = instrument;
422      region = instrument ? instrument->GetFirstRegion() : 0;      regions.update(instrument);
423        region = regions.first();
424      queue_draw();      queue_draw();
425      region_selected();      region_selected();
426        dimensionManager.set_region(region);
427  }  }
428    
429  bool RegionChooser::on_button_release_event(GdkEventButton* event)  bool RegionChooser::on_button_release_event(GdkEventButton* event)
430  {  {
431        const int k = x_to_key(event->x, get_width() - 1);
432    
433        // handle-note off on virtual keyboard
434        if (event->type == GDK_BUTTON_RELEASE) {
435            int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
436                           int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
437            if (velocity <= 0) velocity = 1;
438            switch (m_VirtKeybModeChoice.get_value()) {
439                case VIRT_KEYBOARD_MODE_CHORD:
440                    if (event->y >= REGION_BLOCK_HEIGHT)
441                        keyboard_key_released_signal.emit(k, velocity);
442                    break;
443                case VIRT_KEYBOARD_MODE_NORMAL:
444                default:
445                    if (currentActiveKey >= 0 && currentActiveKey <= 127) {
446                        keyboard_key_released_signal.emit(currentActiveKey, velocity);
447                        currentActiveKey = -1;
448                    }
449                    break;
450            }
451        }
452    
453      if (resize.active) {      if (resize.active) {
454    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
455          get_window()->pointer_ungrab(event->time);          get_window()->pointer_ungrab(event->time);
456    #else
457            Glib::wrap(event->device, true)->ungrab(event->time);
458    #endif
459          resize.active = false;          resize.active = false;
460    
         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();  
             }  
         }  
   
461          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
462              get_window()->set_cursor();              get_window()->set_cursor();
463              cursor_is_resize = false;              cursor_is_resize = false;
464          }          }
465        } else if (move.active) {
466    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
467            get_window()->pointer_ungrab(event->time);
468    #else
469            Glib::wrap(event->device, true)->ungrab(event->time);
470    #endif
471            move.active = false;
472    
473            if (is_in_resize_zone(event->x, event->y)) {
474    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
475                get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
476    #else
477                get_window()->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
478    #endif
479                cursor_is_resize = true;
480            }
481      }      }
482      return true;      return true;
483  }  }
484    
485    void RegionChooser::update_after_resize()
486    {
487        if (resize.mode == resize.moving_high_limit) {
488            if (resize.region->KeyRange.high != resize.pos - 1) {
489                instrument_struct_to_be_changed_signal.emit(instrument);
490                resize.region->SetKeyRange(resize.region->KeyRange.low,
491                                           resize.pos - 1);
492                regions.update(instrument);
493                instrument_changed.emit();
494                instrument_struct_changed_signal.emit(instrument);
495            }
496        } else if (resize.mode == resize.moving_low_limit) {
497            if (resize.region->KeyRange.low != resize.pos) {
498                instrument_struct_to_be_changed_signal.emit(instrument);
499                resize.region->SetKeyRange(resize.pos,
500                                           resize.region->KeyRange.high);
501                regions.update(instrument);
502                instrument_changed.emit();
503                instrument_struct_changed_signal.emit(instrument);
504            }
505        }
506    }
507    
508    void RegionChooser::update_after_move(int pos)
509    {
510        instrument_struct_to_be_changed_signal.emit(instrument);
511        region->SetKeyRange(pos, pos + region->KeyRange.high -
512                            region->KeyRange.low);
513        regions.update(instrument);
514        instrument_changed.emit();
515        instrument_struct_changed_signal.emit(instrument);
516    }
517    
518  bool RegionChooser::on_button_press_event(GdkEventButton* event)  bool RegionChooser::on_button_press_event(GdkEventButton* event)
519  {  {
520      if (!instrument) return true;      if (!instrument) return true;
521    
522      int k = int(event->x / (width - 1) * 128.0);      const int w = get_width() - 1;
523        const int k = x_to_key(event->x, w);
524    
525        if (event->type == GDK_BUTTON_PRESS) {
526            if (event->y >= REGION_BLOCK_HEIGHT) {
527                int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
528                               int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
529                currentActiveKey = k;
530                keyboard_key_hit_signal.emit(k, velocity);
531            }
532        }
533    
534        if (event->y >= REGION_BLOCK_HEIGHT) return true;
535      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
536          gig::Region* r = get_region(k);          gig::Region* r = get_region(k);
537          if (r) {          if (r) {
538              region = r;              region = r;
539              queue_draw();              queue_draw();
540              region_selected();              region_selected();
541                dimensionManager.set_region(region);
542              popup_menu_inside_region->popup(event->button, event->time);              popup_menu_inside_region->popup(event->button, event->time);
543          } else {          } else {
544              new_region_pos = k;              new_region_pos = k;
# Line 271  bool RegionChooser::on_button_press_even Line 546  bool RegionChooser::on_button_press_even
546          }          }
547      } else {      } else {
548          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
549              Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
550              get_window()->pointer_grab(false,              get_window()->pointer_grab(false,
551                                         Gdk::BUTTON_RELEASE_MASK |                                         Gdk::BUTTON_RELEASE_MASK |
552                                         Gdk::POINTER_MOTION_MASK |                                         Gdk::POINTER_MOTION_MASK |
553                                         Gdk::POINTER_MOTION_HINT_MASK,                                         Gdk::POINTER_MOTION_HINT_MASK,
554                                         double_arrow, event->time);                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW),
555                                           event->time);
556    #else
557                Glib::wrap(event->device, true)->grab(get_window(),
558                                                      Gdk::OWNERSHIP_NONE,
559                                                      false,
560                                                      Gdk::BUTTON_RELEASE_MASK |
561                                                      Gdk::POINTER_MOTION_MASK |
562                                                      Gdk::POINTER_MOTION_HINT_MASK,
563                                                      Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW),
564                                                      event->time);
565    #endif
566              resize.active = true;              resize.active = true;
567          } else {          } else {
568              gig::Region* r = get_region(k);              gig::Region* r = get_region(k);
# Line 284  bool RegionChooser::on_button_press_even Line 570  bool RegionChooser::on_button_press_even
570                  region = r;                  region = r;
571                  queue_draw();                  queue_draw();
572                  region_selected();                  region_selected();
573                    dimensionManager.set_region(region);
574    
575    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
576                    get_window()->pointer_grab(false,
577                                               Gdk::BUTTON_RELEASE_MASK |
578                                               Gdk::POINTER_MOTION_MASK |
579                                               Gdk::POINTER_MOTION_HINT_MASK,
580                                               Gdk::Cursor(Gdk::FLEUR),
581                                               event->time);
582    #else
583                    Glib::wrap(event->device, true)->grab(get_window(),
584                                                          Gdk::OWNERSHIP_NONE,
585                                                          false,
586                                                          Gdk::BUTTON_RELEASE_MASK |
587                                                          Gdk::POINTER_MOTION_MASK |
588                                                          Gdk::POINTER_MOTION_HINT_MASK,
589                                                          Gdk::Cursor::create(Gdk::FLEUR),
590                                                          event->time);
591    #endif
592                    move.active = true;
593                    move.offset = event->x - key_to_x(region->KeyRange.low, w);
594              }              }
595          }          }
596      }      }
# Line 292  bool RegionChooser::on_button_press_even Line 599  bool RegionChooser::on_button_press_even
599    
600  gig::Region* RegionChooser::get_region(int key)  gig::Region* RegionChooser::get_region(int key)
601  {  {
602      for (gig::Region *r = instrument->GetFirstRegion() ; r ;      for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
          r = instrument->GetNextRegion()) {  
603          if (key < r->KeyRange.low) return 0;          if (key < r->KeyRange.low) return 0;
604          if (key <= r->KeyRange.high) return r;          if (key <= r->KeyRange.high) return r;
605      }      }
606      return 0;      return 0;
607  }  }
608    
609  bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)  void RegionChooser::motion_resize_region(int x, int y)
610  {  {
611      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);  
612    
613          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;  
614    
615          if (k != resize.pos) {      if (k < resize.min) k = resize.min;
616              if (resize.mode == resize.undecided) {      else if (k > resize.max) k = resize.max;
617                  if (k < resize.pos) {  
618                      // edit high limit of prev_region      if (k != resize.pos) {
619                      resize.max = resize.region->KeyRange.low;          if (resize.mode == resize.undecided) {
620                      resize.region = resize.prev_region;              if (k < resize.pos) {
621                      resize.mode = resize.moving_high_limit;                  // edit high limit of prev_region
622                  } else {                  resize.max = resize.region->KeyRange.low;
623                      // edit low limit of region                  resize.region = resize.prev_region;
624                      resize.min = resize.prev_region->KeyRange.high + 1;                  resize.mode = resize.moving_high_limit;
625                      resize.mode = resize.moving_low_limit;              } else {
626                  }                  // edit low limit of region
627                    resize.min = resize.prev_region->KeyRange.high + 1;
628                    resize.mode = resize.moving_low_limit;
629              }              }
630              Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();          }
631              Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();          resize.pos = k;
632              if (region == resize.region) {  
633                  gc->set_foreground(red);          int x1, x2;
634                  white = gc;          if (resize.mode == resize.moving_high_limit) {
635                if (resize.region->KeyRange.high < resize.pos - 1) {
636                    x1 = resize.region->KeyRange.high;
637                    x2 = resize.pos - 1;
638                } else {
639                    x1 = resize.pos - 1;
640                    x2 = resize.region->KeyRange.high;
641                }
642            } else {
643                if (resize.region->KeyRange.low < resize.pos) {
644                    x1 = resize.region->KeyRange.low;
645                    x2 = resize.pos;
646                } else {
647                    x1 = resize.pos;
648                    x2 = resize.region->KeyRange.low;
649              }              }
650              Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);          }
651              int prevx = int(w * resize.pos / 128.0 + 0.5);          x1 = key_to_x(x1, w);
652              x = int(w * k / 128.0 + 0.5);          x2 = key_to_x(x2 + 1, w) + 1;
653            Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
654              if (resize.mode == resize.moving_high_limit) {  
655                  if (k > resize.pos) {          update_after_resize();
656                      window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);  
657                      window->draw_line(black, prevx, 0, x, 0);          get_window()->invalidate_rect(rect, false);
658                      window->draw_line(black, prevx, h1 - 1, x, h1 - 1);      }
659    }
660    
661    void RegionChooser::motion_move_region(int x, int y)
662    {
663        const int w = get_width() - 1;
664    
665        int l = int(double(x - move.offset) / w * 128.0 + 0.5);
666    
667        if (l == region->KeyRange.low) return;
668        int new_l;
669        int regionsize = region->KeyRange.high - region->KeyRange.low;
670        int a = 0;
671        if (l > region->KeyRange.low) {
672            for (gig::Region* r = regions.first() ; ; r = regions.next()) {
673                if (r != region) {
674                    int b = r ? r->KeyRange.low : 128;
675    
676                    // gap: from a to b (not inclusive b)
677    
678                    if (region->KeyRange.high >= b) {
679                        // not found the current gap yet, just continue
680                  } else {                  } else {
681                      int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);  
682                      window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);                      if (a > l) {
683                            // this gap is too far to the right, break
684                            break;
685                        }
686    
687                        int newhigh = std::min(l + regionsize, b - 1);
688                        int newlo = newhigh - regionsize;
689    
690                        if (newlo >= a) {
691                            // yes it fits - it's a candidate
692                            new_l = newlo;
693                        }
694                  }                  }
695              } else {                  if (!r) break;
696                  if (k < resize.pos) {                  a = r->KeyRange.high + 1;
697                      window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);              }
698                      window->draw_line(black, x, 0, prevx, 0);          }
699                      window->draw_line(black, x, h1 - 1, prevx, h1 - 1);      } else {
700            for (gig::Region* r = regions.first() ; ; r = regions.next()) {
701                if (r != region) {
702                    int b = r ? r->KeyRange.low : 128;
703    
704                    // gap from a to b (not inclusive b)
705    
706                    if (l + regionsize >= b) {
707                        // not found the current gap yet, just continue
708                  } else {                  } else {
709                      int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);  
710                      window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);                      if (a > region->KeyRange.low) {
711                            // this gap is too far to the right, break
712                            break;
713                        }
714    
715                        int newlo = std::max(l, a);
716                        int newhigh = newlo + regionsize;
717    
718                        if (newhigh < b) {
719                            // yes it fits - break as the first one is the best
720                            new_l = newlo;
721                            break;
722                        }
723                  }                  }
724                    if (!r) break;
725                    a = r->KeyRange.high + 1;
726              }              }
             window->draw_line(black, x, 1, x, h1 - 2);  
             resize.pos = k;  
727          }          }
728        }
729        if (new_l == region->KeyRange.low) return;
730    
731        int x1 = key_to_x(std::min(int(region->KeyRange.low), new_l), w);
732        int x2 = key_to_x(std::max(int(region->KeyRange.high),
733                                   new_l + regionsize) + 1, w) + 1;
734    
735        Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
736        update_after_move(new_l);
737    
738        get_window()->invalidate_rect(rect, false);
739    }
740    
741    
742    bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)
743    {
744        Glib::RefPtr<Gdk::Window> window = get_window();
745        int x, y;
746        Gdk::ModifierType state = Gdk::ModifierType(0);
747        window->get_pointer(x, y, state);
748    
749        // handle virtual MIDI keyboard
750        if (m_VirtKeybModeChoice.get_value() != VIRT_KEYBOARD_MODE_CHORD &&
751            currentActiveKey > 0 &&
752            event->y >= REGION_BLOCK_HEIGHT &&
753            event->y < REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT)
754        {
755            const int k = x_to_key(event->x, get_width() - 1);
756            if (k != currentActiveKey) {
757                int velocity =
758                    (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
759                    int(float(event->y - REGION_BLOCK_HEIGHT) /
760                        float(KEYBOARD_HEIGHT) * 128.0f) + 1;
761                if (velocity <= 0) velocity = 1;
762                keyboard_key_released_signal.emit(currentActiveKey, velocity);
763                currentActiveKey = k;
764                keyboard_key_hit_signal.emit(k, velocity);
765            }
766        }
767    
768        if (resize.active) {
769            motion_resize_region(x, y);
770        } else if (move.active) {
771            motion_move_region(x, y);
772      } else {      } else {
773          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
774              if (!cursor_is_resize) {              if (!cursor_is_resize) {
775                  Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
776                  window->set_cursor(double_arrow);                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
777    #else
778                    window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
779    #endif
780                  cursor_is_resize = true;                  cursor_is_resize = true;
781              }              }
782          } else if (cursor_is_resize) {          } else if (cursor_is_resize) {
# Line 375  bool RegionChooser::on_motion_notify_eve Line 789  bool RegionChooser::on_motion_notify_eve
789  }  }
790    
791  bool RegionChooser::is_in_resize_zone(double x, double y) {  bool RegionChooser::is_in_resize_zone(double x, double y) {
792      const int w = width - 1;      const int w = get_width() - 1;
793    
794      if (instrument && y >= 0 && y <= h1) {      if (instrument && y >= 0 && y <= h1) {
795          gig::Region* prev_region = 0;          gig::Region* prev_region = 0;
796          gig::Region* next_region;          gig::Region* next_region;
797          for (gig::Region* r = instrument->GetFirstRegion() ; r ; r = next_region) {          for (gig::Region* r = regions.first(); r ; r = next_region) {
798              next_region = instrument->GetNextRegion();              next_region = regions.next();
799    
800              int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);              int lo = key_to_x(r->KeyRange.low, w);
801              if (x <= lo - 2) break;              if (x <= lo - 2) break;
802              if (x < lo + 2) {              if (x < lo + 2) {
803                  resize.region = r;                  resize.region = r;
# Line 397  bool RegionChooser::is_in_resize_zone(do Line 811  bool RegionChooser::is_in_resize_zone(do
811                      resize.mode = resize.undecided;                      resize.mode = resize.undecided;
812                      resize.min = prev_region->KeyRange.low + 1;                      resize.min = prev_region->KeyRange.low + 1;
813                      resize.prev_region = prev_region;                      resize.prev_region = prev_region;
814                      return true;                      return resize.min != resize.max;
815                  }                  }
816    
817                  // edit low limit                  // edit low limit
818                  resize.mode = resize.moving_low_limit;                  resize.mode = resize.moving_low_limit;
819                  resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;                  resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;
820                  return true;                  return resize.min != resize.max;
821              }              }
822              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
823                  int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);                  int hi = key_to_x(r->KeyRange.high + 1, w);
824                  if (x <= hi - 2) break;                  if (x <= hi - 2) break;
825                  if (x < hi + 2) {                  if (x < hi + 2) {
826                      // edit high limit                      // edit high limit
# Line 415  bool RegionChooser::is_in_resize_zone(do Line 829  bool RegionChooser::is_in_resize_zone(do
829                      resize.mode = resize.moving_high_limit;                      resize.mode = resize.moving_high_limit;
830                      resize.min = r->KeyRange.low + 1;                      resize.min = r->KeyRange.low + 1;
831                      resize.max = next_region ? next_region->KeyRange.low : 128;                      resize.max = next_region ? next_region->KeyRange.low : 128;
832                      return true;                      return resize.min != resize.max;
833                  }                  }
834              }              }
835              prev_region = r;              prev_region = r;
# Line 424  bool RegionChooser::is_in_resize_zone(do Line 838  bool RegionChooser::is_in_resize_zone(do
838      return false;      return false;
839  }  }
840    
841  sigc::signal<void> RegionChooser::signal_region_selected()  sigc::signal<void>& RegionChooser::signal_region_selected()
842  {  {
843      return region_selected;      return region_selected;
844  }  }
845    
846  sigc::signal<void> RegionChooser::signal_instrument_changed()  sigc::signal<void>& RegionChooser::signal_instrument_changed()
847  {  {
848      return instrument_changed;      return instrument_changed;
849  }  }
# Line 437  sigc::signal<void> RegionChooser::signal Line 851  sigc::signal<void> RegionChooser::signal
851  void RegionChooser::show_region_properties()  void RegionChooser::show_region_properties()
852  {  {
853      if (!region) return;      if (!region) return;
854      Gtk::Dialog dialog("Region Properties", true /*modal*/);      Gtk::Dialog dialog(_("Region Properties"), true /*modal*/);
855      // add "Keygroup" checkbox      // add "Keygroup" checkbox
856      Gtk::CheckButton checkBoxKeygroup("Member of a Keygroup (Exclusive Group)");      Gtk::CheckButton checkBoxKeygroup(_("Member of a Keygroup (Exclusive Group)"));
857      checkBoxKeygroup.set_active(region->KeyGroup);      checkBoxKeygroup.set_active(region->KeyGroup);
858      dialog.get_vbox()->pack_start(checkBoxKeygroup);      dialog.get_vbox()->pack_start(checkBoxKeygroup);
859      checkBoxKeygroup.show();      checkBoxKeygroup.show();
860      // add "Keygroup" spinbox      // add "Keygroup" spinbox
861      Gtk::Adjustment adjustment(1, 1, pow(2,32));  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
862        Gtk::Adjustment adjustment(1, 1, 999);
863      Gtk::SpinButton spinBox(adjustment);      Gtk::SpinButton spinBox(adjustment);
864    #else
865        Gtk::SpinButton spinBox(Gtk::Adjustment::create(1, 1, 999));
866    #endif
867      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);
868      dialog.get_vbox()->pack_start(spinBox);      dialog.get_vbox()->pack_start(spinBox);
869      spinBox.show();      spinBox.show();
# Line 461  void RegionChooser::show_region_properti Line 879  void RegionChooser::show_region_properti
879    
880  void RegionChooser::add_region()  void RegionChooser::add_region()
881  {  {
882      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;  
     }  
883    
884      region = instrument->AddRegion();      region = instrument->AddRegion();
885      region->KeyRange.low = region->KeyRange.high = new_region_pos;      region->SetKeyRange(new_region_pos, new_region_pos);
886    
887        instrument_struct_changed_signal.emit(instrument);
888        regions.update(instrument);
889    
     instrument->MoveRegion(region, r);  
890      queue_draw();      queue_draw();
891      region_selected();      region_selected();
892        dimensionManager.set_region(region);
893      instrument_changed();      instrument_changed();
894  }  }
895    
896  void RegionChooser::delete_region()  void RegionChooser::delete_region()
897  {  {
898        instrument_struct_to_be_changed_signal.emit(instrument);
899      instrument->DeleteRegion(region);      instrument->DeleteRegion(region);
900        instrument_struct_changed_signal.emit(instrument);
901        regions.update(instrument);
902    
903      region = 0;      region = 0;
904      queue_draw();      queue_draw();
905      region_selected();      region_selected();
906        dimensionManager.set_region(region);
907      instrument_changed();      instrument_changed();
908  }  }
909    
# Line 495  void RegionChooser::on_dimension_manager Line 918  void RegionChooser::on_dimension_manager
918      region_selected();      region_selected();
919      instrument_changed();      instrument_changed();
920  }  }
921    
922    sigc::signal<void, gig::Instrument*>& RegionChooser::signal_instrument_struct_to_be_changed() {
923        return instrument_struct_to_be_changed_signal;
924    }
925    
926    sigc::signal<void, gig::Instrument*>& RegionChooser::signal_instrument_struct_changed() {
927        return instrument_struct_changed_signal;
928    }
929    
930    sigc::signal<void, gig::Region*>& RegionChooser::signal_region_to_be_changed() {
931        return region_to_be_changed_signal;
932    }
933    
934    sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {
935        return region_changed_signal;
936    }
937    
938    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_hit() {
939        return keyboard_key_hit_signal;
940    }
941    
942    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_released() {
943        return keyboard_key_released_signal;
944    }

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

  ViewVC Help
Powered by ViewVC