/[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 1623 by persson, Fri Jan 4 19:42:45 2008 UTC revision 2641 by schoenebeck, Mon Jun 16 15:24:54 2014 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2008 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>  #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 <math.h>  
30    
31  #include "global.h"  #include "global.h"
32    
33    #define REGION_BLOCK_HEIGHT             30
34    #define KEYBOARD_HEIGHT                 40
35    
36  void SortedRegions::update(gig::Instrument* instrument) {  void SortedRegions::update(gig::Instrument* instrument) {
37      // Usually, the regions in a gig file are ordered after their key      // Usually, the regions in a gig file are ordered after their key
38      // range, but there are files where they are not. The      // range, but there are files where they are not. The
39      // RegionChooser code needs a sorted list of regions.      // RegionChooser code needs a sorted list of regions.
40      regions.clear();      regions.clear();
41      if (instrument) {      if (instrument) {
42          for (gig::Region *r = instrument->GetFirstRegion() ;          for (gig::Region* r = instrument->GetFirstRegion() ;
43               r ;               r ;
44               r = instrument->GetNextRegion()) {               r = instrument->GetNextRegion()) {
45              regions.push_back(r);              regions.push_back(r);
# Line 54  gig::Region* SortedRegions::next() { Line 60  gig::Region* SortedRegions::next() {
60    
61    
62    
63  RegionChooser::RegionChooser()  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);
   
     red = Gdk::Color("#8070ff");  
     grey1 = Gdk::Color("#b0b0b0");  
73    
     colormap->alloc_color(red);  
     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;      move.active = false;
78      cursor_is_resize = false;      cursor_is_resize = false;
79      h1 = 20;      h1 = REGION_BLOCK_HEIGHT;
80    
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 116  RegionChooser::RegionChooser() Line 148  RegionChooser::RegionChooser()
148              sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed)              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      // Now we can allocate any additional resources we need      Gdk::Rectangle rect(x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);
171      Glib::RefPtr<Gdk::Window> window = get_window();      get_window()->invalidate_rect(rect, false);
     gc = Gdk::GC::create(window);  
     window->clear();  
172  }  }
173    
174  bool RegionChooser::on_expose_event(GdkEventExpose* event)  void RegionChooser::on_note_on_event(int key, int velocity) {
175  {      key_pressed[key] = true;
176      Glib::RefPtr<Gdk::Window> window = get_window();      invalidate_key(key);
177      window->clear();      m_VirtKeybVelocityLabel.set_text(ToString(velocity));
178      const int h = 40;  }
     const int w = get_width() - 1;  
     const int bh = int(h * 0.55);  
179    
180      Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();  void RegionChooser::on_note_off_event(int key, int velocity) {
181      Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();      key_pressed[key] = false;
182        invalidate_key(key);
183        m_VirtKeybOffVelocityLabel.set_text(ToString(velocity));
184    }
185    
     Glib::RefPtr<Pango::Context> context = get_pango_context();  
     Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);  
186    
187      window->draw_rectangle(black, false, 0, h1, w, h - 1);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
188      gc->set_foreground(grey1);  bool RegionChooser::on_expose_event(GdkEventExpose* e) {
189      int x1 = int(w * 20.5 / 128.0 + 0.5);      double clipx1 = e->area.x;
190      int x2 = int(w * 109.5 / 128.0 + 0.5);      double clipx2 = e->area.x + e->area.width;
191      window->draw_rectangle(gc, true, 1, h1 + 1,      double clipy1 = e->area.y;
192                             x1 - 1, h - 2);      double clipy2 = e->area.y + e->area.height;
     window->draw_rectangle(white, true, x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);  
     window->draw_rectangle(gc, true, x2 + 1, h1 + 1,  
                            w - x2 - 1, h - 2);  
     int octave = -1;  
     for (int i = 0 ; i < 128 ; i++) {  
         int note = (i + 3) % 12;  
         int x = int(w * i / 128.0 + 0.5);  
193    
194          if (note == 1 || note == 4 || note == 6 || note == 9 || note == 11) {      const Cairo::RefPtr<Cairo::Context>& cr =
195              int x2 = int(w * (i + 0.5) / 128.0 + 0.5);          get_window()->create_cairo_context();
196              window->draw_line(black, x2, h1 + bh, x2, h1 + h);  #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              int x3 = int(w * (i + 1) / 128.0 + 0.5);      cr->save();
206              window->draw_rectangle(black, true, x, h1 + 1, x3 - x + 1, bh);      cr->set_line_width(1);
207          } else if (note == 3 || note == 8) {  
208              window->draw_line(black, x, h1 + 1, x, h1 + h);  #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          if (note == 3) {  #else
211              char buf[30];      const Gdk::RGBA bg = get_style_context()->get_background_color();
212              sprintf(buf, "<span size=\"8000\">%d</span>", octave);  #endif
213              layout->set_markup(buf);      Gdk::Cairo::set_source_rgba(cr, bg);
214              Pango::Rectangle rectangle = layout->get_logical_extents();      cr->paint();
215              double text_w = double(rectangle.get_width()) / Pango::SCALE;  
216              double text_h = double(rectangle.get_height()) / Pango::SCALE;      if (clipy2 > h1) {
217              double x2 = w * (i + 0.75) / 128.0;          draw_keyboard(cr, clipx1, clipx2);
             window->draw_layout(black, int(x2 - text_w / 2 + 1),  
                                 int(h1 + h - text_h + 0.5), layout);  
             octave++;  
         }  
218      }      }
219    
220      if (instrument) {      if (clipy1 < h1 && instrument) {
221          int i = 0;          draw_regions(cr, clipx1, clipx2);
222          gig::Region *next_region;      }
         int x3 = -1;  
         for (gig::Region *r = regions.first() ; r ; r = next_region) {  
223    
224              if (x3 < 0) x3 = int(w * (r->KeyRange.low) / 128.0 + 0.5);      cr->restore();
             next_region = regions.next();  
             if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {  
                 int x2 = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);  
                 window->draw_line(black, x3, 0, x2, 0);  
                 window->draw_line(black, x3, h1 - 1, x2, h1 - 1);  
                 window->draw_line(black, x2, 1, x2, h1 - 2);  
                 window->draw_rectangle(white, true, x3 + 1, 1, x2 - x3 - 1, h1 - 2);  
                 x3 = -1;  
             }  
             i++;  
         }  
225    
226          for (gig::Region *r = regions.first() ; r ; r = regions.next()) {      return true;
227              int x = int(w * (r->KeyRange.low) / 128.0 + 0.5);  }
228              window->draw_line(black, x, 1, x, h1 - 2);  
229          }  void RegionChooser::draw_keyboard(const Cairo::RefPtr<Cairo::Context>& cr,
230                                      int clip_low, int clip_high) {
231        const int h = KEYBOARD_HEIGHT;
232        const int w = get_width() - 1;
233        const int bh = int(h * 0.55);
234    
235        Gdk::Cairo::set_source_rgba(cr, black);
236        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        Gdk::Cairo::set_source_rgba(cr, black);
254    
255        int clipkey1 = std::max(0, x_to_key_right(clip_low - 1, w));
256        int clipkey2 = std::min(x_to_key_right(clip_high - 1, w) + 1, 128);
257    
258          if (region) {      for (int i = clipkey1 ; i < clipkey2 ; i++) {
259              int x1 = int(w * (region->KeyRange.low) / 128.0 + 0.5);          int note = (i + 3) % 12;
260              int x2 = int(w * (region->KeyRange.high + 1) / 128.0 + 0.5);          int x = key_to_x(i, w);
261              gc->set_foreground(red);  
262              window->draw_rectangle(gc, true, x1 + 1, 1, x2 - x1 - 1, h1 - 2);          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) {
275                // 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      }      }
     return true;  
285  }  }
286    
287    
288  void RegionChooser::on_size_request(GtkRequisition* requisition)  void RegionChooser::draw_regions(const Cairo::RefPtr<Cairo::Context>& cr,
289  {                                   int clip_low, int clip_high) {
290      *requisition = GtkRequisition();      const int w = get_width() - 1;
     requisition->height = 40 + 20;  
     requisition->width = 500;  
 }  
291    
292        Gdk::Cairo::set_source_rgba(cr, black);
293        gig::Region* next_region;
294        int x3 = -1;
295        for (gig::Region* r = regions.first() ; r ; r = next_region) {
296            next_region = regions.next();
297    
298  // not used          if (x3 < 0) {
299  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)              x3 = key_to_x(r->KeyRange.low, w);
300  {              if (x3 >= clip_high) break;
301      const int h = 40;          }
302      const int w = get_width();          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                x3 = -1;
320            }
321        }
322    
323        for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
324            int x = key_to_x(r->KeyRange.low, w);
325    
326            if (x < clip_low) continue;
327            if (x >= clip_high) break;
328    
329            cr->move_to(x + 0.5, 1);
330            cr->line_to(x + 0.5, h1 - 1);
331            cr->stroke();
332        }
333    
334        // 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        if (!regions.first()) {
337            Glib::RefPtr<Pango::Context> context = get_pango_context();
338            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        const int note = (key + 3) % 12;
360        return note == 1 || note == 4 || note == 6 || note == 9 || note == 11;
361    }
362    
363    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)
# Line 271  void RegionChooser::set_instrument(gig:: Line 430  void RegionChooser::set_instrument(gig::
430      region = regions.first();      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) {  
                 instrument_struct_to_be_changed_signal.emit(instrument);  
                 resize.region->SetKeyRange(  
                     resize.region->KeyRange.low, // low  
                     resize.pos - 1 // high  
                 );  
                 regions.update(instrument);  
                 instrument_changed.emit();  
                 instrument_struct_changed_signal.emit(instrument);  
             }  
         } else if (resize.mode == resize.moving_low_limit) {  
             if (resize.region->KeyRange.low != resize.pos) {  
                 instrument_struct_to_be_changed_signal.emit(instrument);  
                 resize.region->SetKeyRange(  
                     resize.pos, // low  
                     resize.region->KeyRange.high // high  
                 );  
                 regions.update(instrument);  
                 instrument_changed.emit();  
                 instrument_struct_changed_signal.emit(instrument);  
             }  
         }  
   
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) {      } 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);          get_window()->pointer_ungrab(event->time);
475    #else
476            Glib::wrap(event->device, true)->ungrab(event->time);
477    #endif
478          move.active = false;          move.active = false;
479    
480          if (move.pos) {          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;
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);              instrument_struct_to_be_changed_signal.emit(instrument);
497              region->SetKeyRange(              resize.region->SetKeyRange(resize.region->KeyRange.low,
498                  region->KeyRange.low  + move.pos,                                         resize.pos - 1);
                 region->KeyRange.high + move.pos  
             );  
499              regions.update(instrument);              regions.update(instrument);
500              instrument_changed.emit();              instrument_changed.emit();
501              instrument_struct_changed_signal.emit(instrument);              instrument_struct_changed_signal.emit(instrument);
502          }          }
503        } else if (resize.mode == resize.moving_low_limit) {
504          if (is_in_resize_zone(event->x, event->y)) {          if (resize.region->KeyRange.low != resize.pos) {
505              get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));              instrument_struct_to_be_changed_signal.emit(instrument);
506              cursor_is_resize = true;              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      return true;  }
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 / (get_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            // show dimension manager dialog for this region
544            manage_dimensions();
545        }
546    
547        if (event->y >= REGION_BLOCK_HEIGHT) return true;
548      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
549          gig::Region* r = get_region(k);          gig::Region* r = get_region(k);
550          if (r) {          if (r) {
551              region = r;              region = r;
552              queue_draw();              queue_draw();
553              region_selected();              region_selected();
554                dimensionManager.set_region(region);
555              popup_menu_inside_region->popup(event->button, event->time);              popup_menu_inside_region->popup(event->button, event->time);
556          } else {          } else {
557              new_region_pos = k;              new_region_pos = k;
# Line 349  bool RegionChooser::on_button_press_even Line 559  bool RegionChooser::on_button_press_even
559          }          }
560      } else {      } else {
561          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
562    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
563              get_window()->pointer_grab(false,              get_window()->pointer_grab(false,
564                                         Gdk::BUTTON_RELEASE_MASK |                                         Gdk::BUTTON_RELEASE_MASK |
565                                         Gdk::POINTER_MOTION_MASK |                                         Gdk::POINTER_MOTION_MASK |
566                                         Gdk::POINTER_MOTION_HINT_MASK,                                         Gdk::POINTER_MOTION_HINT_MASK,
567                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW), event->time);                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW),
568                                           event->time);
569    #else
570                Glib::wrap(event->device, true)->grab(get_window(),
571                                                      Gdk::OWNERSHIP_NONE,
572                                                      false,
573                                                      Gdk::BUTTON_RELEASE_MASK |
574                                                      Gdk::POINTER_MOTION_MASK |
575                                                      Gdk::POINTER_MOTION_HINT_MASK,
576                                                      Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW),
577                                                      event->time);
578    #endif
579              resize.active = true;              resize.active = true;
580          } else {          } else {
581              gig::Region* r = get_region(k);              gig::Region* r = get_region(k);
# Line 361  bool RegionChooser::on_button_press_even Line 583  bool RegionChooser::on_button_press_even
583                  region = r;                  region = r;
584                  queue_draw();                  queue_draw();
585                  region_selected();                  region_selected();
586                    dimensionManager.set_region(region);
587    
588    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
589                  get_window()->pointer_grab(false,                  get_window()->pointer_grab(false,
590                                             Gdk::BUTTON_RELEASE_MASK |                                             Gdk::BUTTON_RELEASE_MASK |
591                                             Gdk::POINTER_MOTION_MASK |                                             Gdk::POINTER_MOTION_MASK |
592                                             Gdk::POINTER_MOTION_HINT_MASK,                                             Gdk::POINTER_MOTION_HINT_MASK,
593                                             Gdk::Cursor(Gdk::FLEUR), event->time);                                             Gdk::Cursor(Gdk::FLEUR),
594                                               event->time);
595    #else
596                    Glib::wrap(event->device, true)->grab(get_window(),
597                                                          Gdk::OWNERSHIP_NONE,
598                                                          false,
599                                                          Gdk::BUTTON_RELEASE_MASK |
600                                                          Gdk::POINTER_MOTION_MASK |
601                                                          Gdk::POINTER_MOTION_HINT_MASK,
602                                                          Gdk::Cursor::create(Gdk::FLEUR),
603                                                          event->time);
604    #endif
605                  move.active = true;                  move.active = true;
606                  move.from_x = event->x;                  move.offset = event->x - key_to_x(region->KeyRange.low, w);
                 move.pos = 0;  
607              }              }
608          }          }
609      }      }
# Line 378  bool RegionChooser::on_button_press_even Line 612  bool RegionChooser::on_button_press_even
612    
613  gig::Region* RegionChooser::get_region(int key)  gig::Region* RegionChooser::get_region(int key)
614  {  {
615      gig::Region* prev_region = 0;      for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
     gig::Region* next_region;  
     for (gig::Region *r = regions.first() ; r ; r = next_region) {  
         next_region = regions.next();  
   
616          if (key < r->KeyRange.low) return 0;          if (key < r->KeyRange.low) return 0;
617          if (key <= r->KeyRange.high) {          if (key <= r->KeyRange.high) return r;
             move.touch_left = prev_region && prev_region->KeyRange.high + 1 == r->KeyRange.low;  
             move.touch_right = next_region && r->KeyRange.high + 1 == next_region->KeyRange.low;  
             return r;  
         }  
         prev_region = r;  
618      }      }
619      return 0;      return 0;
620  }  }
# Line 397  gig::Region* RegionChooser::get_region(i Line 622  gig::Region* RegionChooser::get_region(i
622  void RegionChooser::motion_resize_region(int x, int y)  void RegionChooser::motion_resize_region(int x, int y)
623  {  {
624      const int w = get_width() - 1;      const int w = get_width() - 1;
     Glib::RefPtr<Gdk::Window> window = get_window();  
625    
626      int k = int(double(x) / w * 128.0 + 0.5);      int k = int(double(x) / w * 128.0 + 0.5);
627    
# Line 417  void RegionChooser::motion_resize_region Line 641  void RegionChooser::motion_resize_region
641                  resize.mode = resize.moving_low_limit;                  resize.mode = resize.moving_low_limit;
642              }              }
643          }          }
644          Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();          resize.pos = k;
         Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();  
         if (region == resize.region) {  
             gc->set_foreground(red);  
             white = gc;  
         }  
         Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);  
         int prevx = int(w * resize.pos / 128.0 + 0.5);  
         x = int(w * k / 128.0 + 0.5);  
645    
646            int x1, x2;
647          if (resize.mode == resize.moving_high_limit) {          if (resize.mode == resize.moving_high_limit) {
648              if (k > resize.pos) {              if (resize.region->KeyRange.high < resize.pos - 1) {
649                  window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);                  x1 = resize.region->KeyRange.high;
650                  window->draw_line(black, prevx, 0, x, 0);                  x2 = resize.pos - 1;
                 window->draw_line(black, prevx, h1 - 1, x, h1 - 1);  
651              } else {              } else {
652                  int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);                  x1 = resize.pos - 1;
653                  window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);                  x2 = resize.region->KeyRange.high;
654              }              }
655          } else {          } else {
656              if (k < resize.pos) {              if (resize.region->KeyRange.low < resize.pos) {
657                  window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);                  x1 = resize.region->KeyRange.low;
658                  window->draw_line(black, x, 0, prevx, 0);                  x2 = resize.pos;
                 window->draw_line(black, x, h1 - 1, prevx, h1 - 1);  
659              } else {              } else {
660                  int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);                  x1 = resize.pos;
661                  window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);                  x2 = resize.region->KeyRange.low;
662              }              }
663          }          }
664          window->draw_line(black, x, 1, x, h1 - 2);          x1 = key_to_x(x1, w);
665          resize.pos = k;          x2 = key_to_x(x2 + 1, w) + 1;
666            Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
667    
668            update_after_resize();
669    
670            get_window()->invalidate_rect(rect, false);
671      }      }
672  }  }
673    
674  void RegionChooser::motion_move_region(int x, int y)  void RegionChooser::motion_move_region(int x, int y)
675  {  {
676      const int w = get_width() - 1;      const int w = get_width() - 1;
     Glib::RefPtr<Gdk::Window> window = get_window();  
677    
678      int k = int(double(x - move.from_x) / w * 128.0 + 0.5);      int l = int(double(x - move.offset) / w * 128.0 + 0.5);
679      if (k == move.pos) return;  
680      int new_k;      if (l == region->KeyRange.low) return;
681      bool new_touch_left;      int new_l;
682      bool new_touch_right;      int regionsize = region->KeyRange.high - region->KeyRange.low;
683      int a = 0;      int a = 0;
684      if (k > move.pos) {      if (l > region->KeyRange.low) {
685          for (gig::Region* r = regions.first() ; ; r = regions.next()) {          for (gig::Region* r = regions.first() ; ; r = regions.next()) {
686              if (r != region) {              if (r != region) {
687                  int b = r ? r->KeyRange.low : 128;                  int b = r ? r->KeyRange.low : 128;
688    
689                  // gap: from a to b (not inclusive b)                  // gap: from a to b (not inclusive b)
690    
691                  if (region->KeyRange.high + move.pos >= b) {                  if (region->KeyRange.high >= b) {
692                      // not found the current gap yet, just continue                      // not found the current gap yet, just continue
693                  } else {                  } else {
694    
695                      if (a > region->KeyRange.low + k) {                      if (a > l) {
696                          // this gap is too far to the right, break                          // this gap is too far to the right, break
697                          break;                          break;
698                      }                      }
699    
700                      int newhigh = std::min(region->KeyRange.high + k, b - 1);                      int newhigh = std::min(l + regionsize, b - 1);
701                      int newlo = newhigh - (region->KeyRange.high - region->KeyRange.low);                      int newlo = newhigh - regionsize;
702    
703                      if (newlo >= a) {                      if (newlo >= a) {
704                          // yes it fits - it's a candidate                          // yes it fits - it's a candidate
705                          new_k = newlo - region->KeyRange.low;                          new_l = newlo;
                         new_touch_left = a > 0 && a == newlo;  
                         new_touch_right = b < 128 && newhigh + 1 == b;  
706                      }                      }
707                  }                  }
708                  if (!r) break;                  if (!r) break;
# Line 499  void RegionChooser::motion_move_region(i Line 716  void RegionChooser::motion_move_region(i
716    
717                  // gap from a to b (not inclusive b)                  // gap from a to b (not inclusive b)
718    
719                  if (region->KeyRange.high + k >= b) {                  if (l + regionsize >= b) {
720                      // not found the current gap yet, just continue                      // not found the current gap yet, just continue
721                  } else {                  } else {
722    
723                      if (a > region->KeyRange.low + move.pos) {                      if (a > region->KeyRange.low) {
724                          // this gap is too far to the right, break                          // this gap is too far to the right, break
725                          break;                          break;
726                      }                      }
727    
728                      int newlo = std::max(region->KeyRange.low + k, a);                      int newlo = std::max(l, a);
729                      int newhigh = newlo + (region->KeyRange.high - region->KeyRange.low);                      int newhigh = newlo + regionsize;
730    
731                      if (newhigh < b) {                      if (newhigh < b) {
732                          // yes it fits - break as the first one is the best                          // yes it fits - break as the first one is the best
733                          new_k = newlo - region->KeyRange.low;                          new_l = newlo;
                         new_touch_left = a > 0 && a == newlo;  
                         new_touch_right = b < 128 && newhigh + 1 == b;  
734                          break;                          break;
735                      }                      }
736                  }                  }
# Line 524  void RegionChooser::motion_move_region(i Line 739  void RegionChooser::motion_move_region(i
739              }              }
740          }          }
741      }      }
742      k = new_k;      if (new_l == region->KeyRange.low) return;
     if (k == move.pos) return;  
743    
744      Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);      int x1 = key_to_x(std::min(int(region->KeyRange.low), new_l), w);
745      int prevx = int(w * (move.pos + region->KeyRange.low) / 128.0 + 0.5);      int x2 = key_to_x(std::max(int(region->KeyRange.high),
746      x = int(w * (k + region->KeyRange.low) / 128.0 + 0.5);                                 new_l + regionsize) + 1, w) + 1;
     int prevx2 = int(w * (move.pos + region->KeyRange.high + 1) / 128.0 + 0.5);  
     int x2 = int(w * (k + region->KeyRange.high + 1) / 128.0 + 0.5);  
     Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();  
     gc->set_foreground(red);  
   
     if (!new_touch_left) window->draw_line(black, x, 1, x, h1 - 2);  
     if (!new_touch_right) window->draw_line(black, x2, 1, x2, h1 - 2);  
   
     if (k > move.pos) {  
         window->draw_rectangle(bg, true, prevx + (move.touch_left ? 1 : 0), 0,  
                                std::min(x, prevx2 + 1 - (move.touch_right ? 1 : 0)) -  
                                (prevx + (move.touch_left ? 1 : 0)), h1);  
   
         window->draw_line(black, std::max(x, prevx2 + 1), 0, x2, 0);  
         window->draw_line(black, std::max(x, prevx2 + 1), h1 - 1, x2, h1 - 1);  
         window->draw_rectangle(gc, true, std::max(x + 1, prevx2), 1,  
                                x2 - std::max(x + 1, prevx2), h1 - 2);  
     } else {  
         window->draw_rectangle(bg, true, std::max(x2 + 1, prevx + (move.touch_left ? 1 : 0)), 0,  
                                prevx2 + 1 - (move.touch_right ? 1 : 0) -  
                                std::max(x2 + 1, prevx + (move.touch_left ? 1 : 0)), h1);  
   
         window->draw_line(black, x, 0, std::min(x2, prevx - 1), 0);  
         window->draw_line(black, x, h1 - 1, std::min(x2, prevx - 1), h1 - 1);  
747    
748          window->draw_rectangle(gc, true, x + 1, 1, std::min(x2 - 1, prevx) - x, h1 - 2);      Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
749      }      update_after_move(new_l);
750    
751      move.pos = k;      get_window()->invalidate_rect(rect, false);
     move.touch_left = new_touch_left;  
     move.touch_right = new_touch_right;  
752  }  }
753    
754    
# Line 571  bool RegionChooser::on_motion_notify_eve Line 759  bool RegionChooser::on_motion_notify_eve
759      Gdk::ModifierType state = Gdk::ModifierType(0);      Gdk::ModifierType state = Gdk::ModifierType(0);
760      window->get_pointer(x, y, state);      window->get_pointer(x, y, state);
761    
762        // handle virtual MIDI keyboard
763        if (m_VirtKeybModeChoice.get_value() != VIRT_KEYBOARD_MODE_CHORD &&
764            currentActiveKey > 0 &&
765            event->y >= REGION_BLOCK_HEIGHT &&
766            event->y < REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT)
767        {
768            const int k = x_to_key(event->x, get_width() - 1);
769            if (k != currentActiveKey) {
770                int velocity =
771                    (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
772                    int(float(event->y - REGION_BLOCK_HEIGHT) /
773                        float(KEYBOARD_HEIGHT) * 128.0f) + 1;
774                if (velocity <= 0) velocity = 1;
775                keyboard_key_released_signal.emit(currentActiveKey, velocity);
776                currentActiveKey = k;
777                keyboard_key_hit_signal.emit(k, velocity);
778            }
779        }
780    
781      if (resize.active) {      if (resize.active) {
782          motion_resize_region(x, y);          motion_resize_region(x, y);
783      } else if (move.active) {      } else if (move.active) {
# Line 578  bool RegionChooser::on_motion_notify_eve Line 785  bool RegionChooser::on_motion_notify_eve
785      } else {      } else {
786          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
787              if (!cursor_is_resize) {              if (!cursor_is_resize) {
788    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
789                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
790    #else
791                    window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
792    #endif
793                  cursor_is_resize = true;                  cursor_is_resize = true;
794              }              }
795          } else if (cursor_is_resize) {          } else if (cursor_is_resize) {
# Line 599  bool RegionChooser::is_in_resize_zone(do Line 810  bool RegionChooser::is_in_resize_zone(do
810          for (gig::Region* r = regions.first(); r ; r = next_region) {          for (gig::Region* r = regions.first(); r ; r = next_region) {
811              next_region = regions.next();              next_region = regions.next();
812    
813              int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);              int lo = key_to_x(r->KeyRange.low, w);
814              if (x <= lo - 2) break;              if (x <= lo - 2) break;
815              if (x < lo + 2) {              if (x < lo + 2) {
816                  resize.region = r;                  resize.region = r;
# Line 622  bool RegionChooser::is_in_resize_zone(do Line 833  bool RegionChooser::is_in_resize_zone(do
833                  return resize.min != resize.max;                  return resize.min != resize.max;
834              }              }
835              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
836                  int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);                  int hi = key_to_x(r->KeyRange.high + 1, w);
837                  if (x <= hi - 2) break;                  if (x <= hi - 2) break;
838                  if (x < hi + 2) {                  if (x < hi + 2) {
839                      // edit high limit                      // edit high limit
# Line 653  sigc::signal<void>& RegionChooser::signa Line 864  sigc::signal<void>& RegionChooser::signa
864  void RegionChooser::show_region_properties()  void RegionChooser::show_region_properties()
865  {  {
866      if (!region) return;      if (!region) return;
867      Gtk::Dialog dialog("Region Properties", true /*modal*/);      Gtk::Dialog dialog(_("Region Properties"), true /*modal*/);
868      // add "Keygroup" checkbox      // add "Keygroup" checkbox
869      Gtk::CheckButton checkBoxKeygroup("Member of a Keygroup (Exclusive Group)");      Gtk::CheckButton checkBoxKeygroup(_("Member of a Keygroup (Exclusive Group)"));
870      checkBoxKeygroup.set_active(region->KeyGroup);      checkBoxKeygroup.set_active(region->KeyGroup);
871      dialog.get_vbox()->pack_start(checkBoxKeygroup);      dialog.get_vbox()->pack_start(checkBoxKeygroup);
872      checkBoxKeygroup.show();      checkBoxKeygroup.show();
873      // add "Keygroup" spinbox      // add "Keygroup" spinbox
874      Gtk::Adjustment adjustment(1, 1, pow(2,32));  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
875        Gtk::Adjustment adjustment(1, 1, 999);
876      Gtk::SpinButton spinBox(adjustment);      Gtk::SpinButton spinBox(adjustment);
877    #else
878        Gtk::SpinButton spinBox(Gtk::Adjustment::create(1, 1, 999));
879    #endif
880      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);
881      dialog.get_vbox()->pack_start(spinBox);      dialog.get_vbox()->pack_start(spinBox);
882      spinBox.show();      spinBox.show();
# Line 687  void RegionChooser::add_region() Line 902  void RegionChooser::add_region()
902    
903      queue_draw();      queue_draw();
904      region_selected();      region_selected();
905        dimensionManager.set_region(region);
906      instrument_changed();      instrument_changed();
907  }  }
908    
# Line 700  void RegionChooser::delete_region() Line 916  void RegionChooser::delete_region()
916      region = 0;      region = 0;
917      queue_draw();      queue_draw();
918      region_selected();      region_selected();
919        dimensionManager.set_region(region);
920      instrument_changed();      instrument_changed();
921  }  }
922    
# Line 730  sigc::signal<void, gig::Region*>& Region Line 947  sigc::signal<void, gig::Region*>& Region
947  sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {  sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {
948      return region_changed_signal;      return region_changed_signal;
949  }  }
950    
951    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_hit() {
952        return keyboard_key_hit_signal;
953    }
954    
955    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_released() {
956        return keyboard_key_released_signal;
957    }

Legend:
Removed from v.1623  
changed lines
  Added in v.2641

  ViewVC Help
Powered by ViewVC