/[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 1658 by persson, Sat Feb 2 08:52:48 2008 UTC revision 2841 by persson, Sun Aug 30 10:00:49 2015 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2008 Andreas Persson   * Copyright (C) 2006-2015 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 18  Line 18 
18   */   */
19    
20  #include "regionchooser.h"  #include "regionchooser.h"
21    
22  #include <algorithm>  #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    #include "Settings.h"
33    
34    #define REGION_BLOCK_HEIGHT             30
35    #define KEYBOARD_HEIGHT                 40
36    
37  void SortedRegions::update(gig::Instrument* instrument) {  void SortedRegions::update(gig::Instrument* instrument) {
38      // Usually, the regions in a gig file are ordered after their key      // Usually, the regions in a gig file are ordered after their key
# Line 33  void SortedRegions::update(gig::Instrume Line 40  void SortedRegions::update(gig::Instrume
40      // RegionChooser code needs a sorted list of regions.      // RegionChooser code needs a sorted list of regions.
41      regions.clear();      regions.clear();
42      if (instrument) {      if (instrument) {
43          for (gig::Region *r = instrument->GetFirstRegion() ;          for (gig::Region* r = instrument->GetFirstRegion() ;
44               r ;               r ;
45               r = instrument->GetNextRegion()) {               r = instrument->GetNextRegion()) {
46              regions.push_back(r);              regions.push_back(r);
# Line 48  gig::Region* SortedRegions::first() { Line 55  gig::Region* SortedRegions::first() {
55  }  }
56    
57  gig::Region* SortedRegions::next() {  gig::Region* SortedRegions::next() {
58      region_iterator++;      ++region_iterator;
59      return region_iterator == regions.end() ? 0 : *region_iterator;      return region_iterator == regions.end() ? 0 : *region_iterator;
60  }  }
61    
62    
63    
64  RegionChooser::RegionChooser()  RegionChooser::RegionChooser() :
65        activeKeyColor("red"),
66        red("#8070ff"),
67        grey1("grey69"),
68        white("white"),
69        black("black"),
70        m_VirtKeybModeChoice(_("Virtual Keyboard Mode")),
71        currentActiveKey(-1)
72  {  {
73      Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();      set_size_request(500, KEYBOARD_HEIGHT + REGION_BLOCK_HEIGHT);
74    
     red = Gdk::Color("#8070ff");  
     grey1 = Gdk::Color("#b0b0b0");  
     activeKeyColor = Gdk::Color("#ff0000");  
     white = Gdk::Color("#ffffff");  
     black = Gdk::Color("#000000");  
   
     colormap->alloc_color(red);  
     colormap->alloc_color(grey1);  
     colormap->alloc_color(activeKeyColor);  
     colormap->alloc_color(white);  
     colormap->alloc_color(black);  
75      instrument = 0;      instrument = 0;
76      region = 0;      region = 0;
77      resize.active = false;      resize.active = false;
78      move.active = false;      move.active = false;
79      cursor_is_resize = false;      cursor_is_resize = false;
80      h1 = 20;      h1 = REGION_BLOCK_HEIGHT;
81    
82        // properties of the virtual keyboard
83        {
84            const char* choices[] = { _("normal"), _("chord"), 0 };
85            static const virt_keyboard_mode_t values[] = {
86                VIRT_KEYBOARD_MODE_NORMAL,
87                VIRT_KEYBOARD_MODE_CHORD
88            };
89            m_VirtKeybModeChoice.set_choices(choices, values);
90            m_VirtKeybModeChoice.set_value(VIRT_KEYBOARD_MODE_NORMAL);
91        }
92        m_VirtKeybVelocityLabelDescr.set_text(_("Note-On Velocity:"));
93        m_VirtKeybVelocityLabel.set_text("-");
94        m_VirtKeybOffVelocityLabelDescr.set_text(_("Note-Off Velocity:"));
95        m_VirtKeybOffVelocityLabel.set_text("-");
96        m_VirtKeybPropsBox.pack_start(m_VirtKeybModeChoice.label, Gtk::PACK_SHRINK);
97        m_VirtKeybPropsBox.pack_start(m_VirtKeybModeChoice.widget, Gtk::PACK_SHRINK);
98        m_VirtKeybPropsBox.pack_start(m_VirtKeybVelocityLabelDescr, Gtk::PACK_SHRINK);
99        m_VirtKeybPropsBox.pack_start(m_VirtKeybVelocityLabel, Gtk::PACK_SHRINK);
100        m_VirtKeybPropsBox.pack_start(m_VirtKeybOffVelocityLabelDescr, Gtk::PACK_SHRINK);
101        m_VirtKeybPropsBox.pack_start(m_VirtKeybOffVelocityLabel, Gtk::PACK_SHRINK);
102        m_VirtKeybPropsBox.set_spacing(10);
103        m_VirtKeybPropsBox.show();
104        for (int i = 0 ; i < 128 ; i++) key_pressed[i] = false;
105    
106      actionGroup = Gtk::ActionGroup::create();      actionGroup = Gtk::ActionGroup::create();
107      actionGroup->add(Gtk::Action::create("Properties",      actionGroup->add(Gtk::Action::create("Properties",
# Line 122  RegionChooser::RegionChooser() Line 149  RegionChooser::RegionChooser()
149              sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed)              sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed)
150          )          )
151      );      );
152        keyboard_key_hit_signal.connect(
153            sigc::mem_fun(*this, &RegionChooser::on_note_on_event)
154        );
155        keyboard_key_released_signal.connect(
156            sigc::mem_fun(*this, &RegionChooser::on_note_off_event)
157        );
158        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."));
159  }  }
160    
161  RegionChooser::~RegionChooser()  RegionChooser::~RegionChooser()
162  {  {
163  }  }
164    
165    void RegionChooser::invalidate_key(int key) {
166        const int h = KEYBOARD_HEIGHT;
167        const int w = get_width() - 1;
168        int x1 = key_to_x(key - 0.5, w);
169        int x2 = key_to_x(key + 1.5, w);
170    
171        Gdk::Rectangle rect(x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);
172        get_window()->invalidate_rect(rect, false);
173    }
174    
175  void RegionChooser::on_note_on_event(int key, int velocity) {  void RegionChooser::on_note_on_event(int key, int velocity) {
176      draw_region(key, key+1, activeKeyColor);      key_pressed[key] = true;
177        invalidate_key(key);
178        m_VirtKeybVelocityLabel.set_text(ToString(velocity));
179  }  }
180    
181  void RegionChooser::on_note_off_event(int key, int velocity) {  void RegionChooser::on_note_off_event(int key, int velocity) {
182      if (is_black_key(key))      key_pressed[key] = false;
183          draw_region(key, key+1, black);      invalidate_key(key);
184      else      m_VirtKeybOffVelocityLabel.set_text(ToString(velocity));
         draw_region(key, key+1, white);  
185  }  }
186    
 void RegionChooser::on_realize()  
 {  
     // We need to call the base on_realize()  
     Gtk::DrawingArea::on_realize();  
187    
188      // Now we can allocate any additional resources we need  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
189      Glib::RefPtr<Gdk::Window> window = get_window();  bool RegionChooser::on_expose_event(GdkEventExpose* e) {
190      gc = Gdk::GC::create(window);      double clipx1 = e->area.x;
191      window->clear();      double clipx2 = e->area.x + e->area.width;
192        double clipy1 = e->area.y;
193        double clipy2 = e->area.y + e->area.height;
194    
195        const Cairo::RefPtr<Cairo::Context>& cr =
196            get_window()->create_cairo_context();
197    #if 0
198  }  }
199    #endif
200    #else
201    bool RegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) {
202        double clipx1, clipx2, clipy1, clipy2;
203        cr->get_clip_extents(clipx1, clipy1, clipx2, clipy2);
204    #endif
205    
206  bool RegionChooser::on_expose_event(GdkEventExpose* event)      cr->save();
207  {      cr->set_line_width(1);
208      Glib::RefPtr<Gdk::Window> window = get_window();  
209      window->clear();  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
210      const int h = 40;      const Gdk::Color bg = get_style()->get_bg(Gtk::STATE_NORMAL);
211    #else
212        const Gdk::RGBA bg = get_style_context()->get_background_color();
213    #endif
214        Gdk::Cairo::set_source_rgba(cr, bg);
215        cr->paint();
216    
217        if (clipy2 > h1) {
218            draw_keyboard(cr, clipx1, clipx2);
219        }
220    
221        if (clipy1 < h1 && instrument) {
222            draw_regions(cr, clipx1, clipx2);
223        }
224    
225        cr->restore();
226    
227        return true;
228    }
229    
230    void RegionChooser::draw_keyboard(const Cairo::RefPtr<Cairo::Context>& cr,
231                                      int clip_low, int clip_high) {
232        const int h = KEYBOARD_HEIGHT;
233      const int w = get_width() - 1;      const int w = get_width() - 1;
234      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
235    
236      Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();      Gdk::Cairo::set_source_rgba(cr, black);
237      Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();      cr->rectangle(0.5, h1 + 0.5, w, h - 1);
238        cr->stroke();
239    
240        int x1 = key_to_x(20.5, w);
241        Gdk::Cairo::set_source_rgba(cr, grey1);
242        cr->rectangle(1, h1 + 1, x1 - 1, h - 2);
243        cr->fill();
244    
245        int x2 = key_to_x(109.5, w);
246        Gdk::Cairo::set_source_rgba(cr, white);
247        cr->rectangle(x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);
248        cr->fill();
249    
250        Gdk::Cairo::set_source_rgba(cr, grey1);
251        cr->rectangle(x2 + 1, h1 + 1, w - x2 - 1, h - 2);
252        cr->fill();
253    
254      window->draw_rectangle(black, false, 0, h1, w, h - 1);      Gdk::Cairo::set_source_rgba(cr, black);
     gc->set_foreground(grey1);  
     int x1 = int(w * 20.5 / 128.0 + 0.5);  
     int x2 = int(w * 109.5 / 128.0 + 0.5);  
     window->draw_rectangle(gc, true, 1, h1 + 1,  
                            x1 - 1, h - 2);  
     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);  
     for (int i = 0 ; i < 128 ; i++) {  
         int note = (i + 3) % 12;  
         int x = int(w * i / 128.0 + 0.5);  
255    
256          if (note == 1 || note == 4 || note == 6 || note == 9 || note == 11) {      int clipkey1 = std::max(0, x_to_key_right(clip_low - 1, w));
257              int x2 = int(w * (i + 0.5) / 128.0 + 0.5);      int clipkey2 = std::min(x_to_key_right(clip_high - 1, w) + 1, 128);
             window->draw_line(black, x2, h1 + bh, x2, h1 + h);  
258    
259              int x3 = int(w * (i + 1) / 128.0 + 0.5);      for (int i = clipkey1 ; i < clipkey2 ; i++) {
260              window->draw_rectangle(black, true, x, h1 + 1, x3 - x + 1, bh);          int note = (i + 3) % 12;
261            int x = key_to_x(i, w);
262    
263            if (note == 1 || note == 4 || note == 6 ||
264                note == 9 || note == 11) {
265                // black key: short line in the middle, with a rectangle
266                // on top
267                int x2 = key_to_x(i + 0.5, w);
268                cr->move_to(x2 + 0.5, h1 + bh + 0.5);
269                cr->line_to(x2 + 0.5, h1 + h - 1);
270                cr->stroke();
271    
272                int x3 = key_to_x(i + 1, w);
273                cr->rectangle(x, h1 + 1, x3 - x + 1, bh);
274                cr->fill();
275          } else if (note == 3 || note == 8) {          } else if (note == 3 || note == 8) {
276              window->draw_line(black, x, h1 + 1, x, h1 + h);              // C or F: long line to the left
277                cr->move_to(x + 0.5, h1 + 1);
278                cr->line_to(x + 0.5, h1 + h - 1);
279                cr->stroke();
280          }          }
281          if (note == 3) draw_digit(i);  
282            if (key_pressed[i]) draw_key(cr, i);
283    
284            if (note == 3) draw_digit(cr, i);
285      }      }
286    }
287    
     if (instrument) {  
         int i = 0;  
         gig::Region *next_region;  
         int x3 = -1;  
         for (gig::Region *r = regions.first() ; r ; r = next_region) {  
288    
289              if (x3 < 0) x3 = int(w * (r->KeyRange.low) / 128.0 + 0.5);  void RegionChooser::draw_regions(const Cairo::RefPtr<Cairo::Context>& cr,
290              next_region = regions.next();                                   int clip_low, int clip_high) {
291              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {      const int w = get_width() - 1;
                 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++;  
         }  
292    
293          for (gig::Region *r = regions.first() ; r ; r = regions.next()) {      Gdk::Cairo::set_source_rgba(cr, black);
294              int x = int(w * (r->KeyRange.low) / 128.0 + 0.5);      gig::Region* next_region;
295              window->draw_line(black, x, 1, x, h1 - 2);      int x3 = -1;
296          }      for (gig::Region* r = regions.first() ; r ; r = next_region) {
297            next_region = regions.next();
298    
299          if (region) {          if (x3 < 0) {
300              int x1 = int(w * (region->KeyRange.low) / 128.0 + 0.5);              x3 = key_to_x(r->KeyRange.low, w);
301              int x2 = int(w * (region->KeyRange.high + 1) / 128.0 + 0.5);              if (x3 >= clip_high) break;
302              gc->set_foreground(red);          }
303              window->draw_rectangle(gc, true, x1 + 1, 1, x2 - x1 - 1, h1 - 2);          if (!next_region ||
304                r->KeyRange.high + 1 != next_region->KeyRange.low ||
305                r == region || next_region == region) {
306    
307                int x2 = key_to_x(r->KeyRange.high + 1, w);
308                if (x2 >= clip_low) {
309                    cr->move_to(x3, 0.5);
310                    cr->line_to(x2 + 0.5, 0.5);
311                    cr->line_to(x2 + 0.5, h1 - 0.5);
312                    cr->line_to(x3, h1 - 0.5);
313                    cr->stroke();
314    
315                    Gdk::Cairo::set_source_rgba(cr, region == r ? red : white);
316                    cr->rectangle(x3 + 1, 1, x2 - x3 - 1, h1 - 2);
317                    cr->fill();
318                    Gdk::Cairo::set_source_rgba(cr, black);
319                }
320                x3 = -1;
321          }          }
322      }      }
     return true;  
 }  
   
323    
324  void RegionChooser::on_size_request(GtkRequisition* requisition)      for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
325  {          int x = key_to_x(r->KeyRange.low, w);
326      *requisition = GtkRequisition();  
327      requisition->height = 40 + 20;          if (x < clip_low) continue;
328      requisition->width = 500;          if (x >= clip_high) break;
329    
330            cr->move_to(x + 0.5, 1);
331            cr->line_to(x + 0.5, h1 - 1);
332            cr->stroke();
333        }
334    
335        // if there is no region yet, show the user some hint text that he may
336        // right click on this area to create a new region
337        if (!regions.first()) {
338            Glib::RefPtr<Pango::Context> context = get_pango_context();
339            Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
340            layout->set_alignment(Pango::ALIGN_CENTER);
341            layout->set_text(Glib::ustring("*** ") + _("Right click here to create a region.") + " ***");
342            layout->set_width(get_width() * Pango::SCALE);
343            //layout->set_height(get_height() * Pango::SCALE);
344            layout->set_spacing(10);
345            Gdk::Cairo::set_source_rgba(cr, red);        
346            // get the text dimensions
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) {  bool RegionChooser::is_black_key(int key) {
# Line 233  bool RegionChooser::is_black_key(int key Line 360  bool RegionChooser::is_black_key(int key
360      return note == 1 || note == 4 || note == 6 || note == 9 || note == 11;      return note == 1 || note == 4 || note == 6 || note == 9 || note == 11;
361  }  }
362    
363  void RegionChooser::draw_digit(int key) {  void RegionChooser::draw_digit(const Cairo::RefPtr<Cairo::Context>& cr,
364      const int h = 40;                                 int key) {
365        const int h = KEYBOARD_HEIGHT;
366      const int w = get_width() - 1;      const int w = get_width() - 1;
367      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(get_pango_context());      Glib::RefPtr<Pango::Layout> layout =
368            Pango::Layout::create(get_pango_context());
369      char buf[30];      char buf[30];
370      sprintf(buf, "<span size=\"8000\">%d</span>", key / 12 - 1);      sprintf(buf, "<span size=\"8000\">%d</span>", key / 12 - 1);
371      layout->set_markup(buf);      layout->set_markup(buf);
# Line 244  void RegionChooser::draw_digit(int key) Line 373  void RegionChooser::draw_digit(int key)
373      double text_w = double(rectangle.get_width()) / Pango::SCALE;      double text_w = double(rectangle.get_width()) / Pango::SCALE;
374      double text_h = double(rectangle.get_height()) / Pango::SCALE;      double text_h = double(rectangle.get_height()) / Pango::SCALE;
375      double x = w * (key + 0.75) / 128.0;      double x = w * (key + 0.75) / 128.0;
376      get_window()->draw_layout(get_style()->get_black_gc(), int(x - text_w / 2 + 1),      Gdk::Cairo::set_source_rgba(cr, black);
377                                int(h1 + h - text_h + 0.5), layout);      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_region(int from, int to, const Gdk::Color& color)  void RegionChooser::draw_key(const Cairo::RefPtr<Cairo::Context>& cr,
386  {                               int key) {
387      const int h = 40;      const int h = KEYBOARD_HEIGHT;
388      const int w = get_width() - 1;      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 + 0.5);      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 + 1, h1 + bh + 1, x2 - x4 - 1, 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 + 1, h1 + bh + 1, x3 - x4 - 1, 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              if (note == 3) draw_digit(i);      case 3: case 8:
413              break;          cr->rectangle(x, h1 + 1, w1, bh);
414          default:          cr->fill();
415              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh - 1);          cr->rectangle(x, h1 + bh + 1, x2 - x, h - bh - 2);
416              break;          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 292  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);
497                resize.region->SetKeyRange(resize.region->KeyRange.low,
498                                           resize.pos - 1);
499                regions.update(instrument);
500                instrument_changed.emit();
501                instrument_struct_changed_signal.emit(instrument);
502            }
503        } else if (resize.mode == resize.moving_low_limit) {
504            if (resize.region->KeyRange.low != resize.pos) {
505              instrument_struct_to_be_changed_signal.emit(instrument);              instrument_struct_to_be_changed_signal.emit(instrument);
506              region->SetKeyRange(              resize.region->SetKeyRange(resize.pos,
507                  region->KeyRange.low  + move.pos,                                         resize.region->KeyRange.high);
                 region->KeyRange.high + move.pos  
             );  
508              regions.update(instrument);              regions.update(instrument);
509              instrument_changed.emit();              instrument_changed.emit();
510              instrument_struct_changed_signal.emit(instrument);              instrument_struct_changed_signal.emit(instrument);
511          }          }
512        }
513    }
514    
515          if (is_in_resize_zone(event->x, event->y)) {  void RegionChooser::update_after_move(int pos)
516              get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));  {
517              cursor_is_resize = true;      instrument_struct_to_be_changed_signal.emit(instrument);
518        const int range = region->KeyRange.high - region->KeyRange.low;
519        const int diff  = pos - int(region->KeyRange.low);
520        region->SetKeyRange(pos, pos + range);
521        if (Settings::singleton()->moveRootNoteWithRegionMoved) {
522            for (int i = 0; i < 256; ++i) {
523                gig::DimensionRegion* dimrgn = region->pDimensionRegions[i];
524                if (!dimrgn || !dimrgn->pSample || !dimrgn->PitchTrack) continue;
525                dimrgn->UnityNote += diff;
526          }          }
527      }      }
528      return true;      regions.update(instrument);
529        instrument_changed.emit();
530        instrument_struct_changed_signal.emit(instrument);
531  }  }
532    
533  bool RegionChooser::on_button_press_event(GdkEventButton* event)  bool RegionChooser::on_button_press_event(GdkEventButton* event)
534  {  {
535      if (!instrument) return true;      if (!instrument) return true;
536    
537      int k = int(event->x / (get_width() - 1) * 128.0);      const int w = get_width() - 1;
538        const int k = x_to_key(event->x, w);
539    
540        if (event->type == GDK_BUTTON_PRESS) {
541            if (event->y >= REGION_BLOCK_HEIGHT) {
542                int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
543                               int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
544                currentActiveKey = k;
545                keyboard_key_hit_signal.emit(k, velocity);
546            }
547        }
548    
549        // left mouse button double click
550        if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
551            if (event->y < REGION_BLOCK_HEIGHT) {
552                // show dimension manager dialog for this region
553                manage_dimensions();
554            }
555        }
556    
557        if (event->y >= REGION_BLOCK_HEIGHT) return true;
558      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
559          gig::Region* r = get_region(k);          gig::Region* r = get_region(k);
560          if (r) {          if (r) {
561              region = r;              region = r;
562              queue_draw();              queue_draw();
563              region_selected();              region_selected();
564                dimensionManager.set_region(region);
565              popup_menu_inside_region->popup(event->button, event->time);              popup_menu_inside_region->popup(event->button, event->time);
566          } else {          } else {
567              new_region_pos = k;              new_region_pos = k;
# Line 370  bool RegionChooser::on_button_press_even Line 569  bool RegionChooser::on_button_press_even
569          }          }
570      } else {      } else {
571          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
572    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
573              get_window()->pointer_grab(false,              get_window()->pointer_grab(false,
574                                         Gdk::BUTTON_RELEASE_MASK |                                         Gdk::BUTTON_RELEASE_MASK |
575                                         Gdk::POINTER_MOTION_MASK |                                         Gdk::POINTER_MOTION_MASK |
576                                         Gdk::POINTER_MOTION_HINT_MASK,                                         Gdk::POINTER_MOTION_HINT_MASK,
577                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW), event->time);                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW),
578                                           event->time);
579    #else
580                Glib::wrap(event->device, true)->grab(get_window(),
581                                                      Gdk::OWNERSHIP_NONE,
582                                                      false,
583                                                      Gdk::BUTTON_RELEASE_MASK |
584                                                      Gdk::POINTER_MOTION_MASK |
585                                                      Gdk::POINTER_MOTION_HINT_MASK,
586                                                      Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW),
587                                                      event->time);
588    #endif
589              resize.active = true;              resize.active = true;
590          } else {          } else {
591              gig::Region* r = get_region(k);              gig::Region* r = get_region(k);
# Line 382  bool RegionChooser::on_button_press_even Line 593  bool RegionChooser::on_button_press_even
593                  region = r;                  region = r;
594                  queue_draw();                  queue_draw();
595                  region_selected();                  region_selected();
596                    dimensionManager.set_region(region);
597    
598    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
599                  get_window()->pointer_grab(false,                  get_window()->pointer_grab(false,
600                                             Gdk::BUTTON_RELEASE_MASK |                                             Gdk::BUTTON_RELEASE_MASK |
601                                             Gdk::POINTER_MOTION_MASK |                                             Gdk::POINTER_MOTION_MASK |
602                                             Gdk::POINTER_MOTION_HINT_MASK,                                             Gdk::POINTER_MOTION_HINT_MASK,
603                                             Gdk::Cursor(Gdk::FLEUR), event->time);                                             Gdk::Cursor(Gdk::FLEUR),
604                                               event->time);
605    #else
606                    Glib::wrap(event->device, true)->grab(get_window(),
607                                                          Gdk::OWNERSHIP_NONE,
608                                                          false,
609                                                          Gdk::BUTTON_RELEASE_MASK |
610                                                          Gdk::POINTER_MOTION_MASK |
611                                                          Gdk::POINTER_MOTION_HINT_MASK,
612                                                          Gdk::Cursor::create(Gdk::FLEUR),
613                                                          event->time);
614    #endif
615                  move.active = true;                  move.active = true;
616                  move.from_x = event->x;                  move.offset = event->x - key_to_x(region->KeyRange.low, w);
                 move.pos = 0;  
617              }              }
618          }          }
619      }      }
# Line 399  bool RegionChooser::on_button_press_even Line 622  bool RegionChooser::on_button_press_even
622    
623  gig::Region* RegionChooser::get_region(int key)  gig::Region* RegionChooser::get_region(int key)
624  {  {
625      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();  
   
626          if (key < r->KeyRange.low) return 0;          if (key < r->KeyRange.low) return 0;
627          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;  
628      }      }
629      return 0;      return 0;
630  }  }
631    
632    void RegionChooser::set_region(gig::Region* region) {
633        this->region = region;
634        queue_draw();
635        region_selected();
636        dimensionManager.set_region(region);
637    }
638    
639  void RegionChooser::motion_resize_region(int x, int y)  void RegionChooser::motion_resize_region(int x, int y)
640  {  {
641      const int w = get_width() - 1;      const int w = get_width() - 1;
     Glib::RefPtr<Gdk::Window> window = get_window();  
642    
643      int k = int(double(x) / w * 128.0 + 0.5);      int k = int(double(x) / w * 128.0 + 0.5);
644    
# Line 438  void RegionChooser::motion_resize_region Line 658  void RegionChooser::motion_resize_region
658                  resize.mode = resize.moving_low_limit;                  resize.mode = resize.moving_low_limit;
659              }              }
660          }          }
661          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);  
662    
663            int x1, x2;
664          if (resize.mode == resize.moving_high_limit) {          if (resize.mode == resize.moving_high_limit) {
665              if (k > resize.pos) {              if (resize.region->KeyRange.high < resize.pos - 1) {
666                  window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);                  x1 = resize.region->KeyRange.high;
667                  window->draw_line(black, prevx, 0, x, 0);                  x2 = resize.pos - 1;
                 window->draw_line(black, prevx, h1 - 1, x, h1 - 1);  
668              } else {              } else {
669                  int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);                  x1 = resize.pos - 1;
670                  window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);                  x2 = resize.region->KeyRange.high;
671              }              }
672          } else {          } else {
673              if (k < resize.pos) {              if (resize.region->KeyRange.low < resize.pos) {
674                  window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);                  x1 = resize.region->KeyRange.low;
675                  window->draw_line(black, x, 0, prevx, 0);                  x2 = resize.pos;
                 window->draw_line(black, x, h1 - 1, prevx, h1 - 1);  
676              } else {              } else {
677                  int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);                  x1 = resize.pos;
678                  window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);                  x2 = resize.region->KeyRange.low;
679              }              }
680          }          }
681          window->draw_line(black, x, 1, x, h1 - 2);          x1 = key_to_x(x1, w);
682          resize.pos = k;          x2 = key_to_x(x2 + 1, w) + 1;
683            Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
684    
685            update_after_resize();
686    
687            get_window()->invalidate_rect(rect, false);
688      }      }
689  }  }
690    
691  void RegionChooser::motion_move_region(int x, int y)  void RegionChooser::motion_move_region(int x, int y)
692  {  {
693      const int w = get_width() - 1;      const int w = get_width() - 1;
     Glib::RefPtr<Gdk::Window> window = get_window();  
694    
695      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);
696      if (k == move.pos) return;  
697      int new_k;      if (l == region->KeyRange.low) return;
698      bool new_touch_left;      int new_l;
699      bool new_touch_right;      int regionsize = region->KeyRange.high - region->KeyRange.low;
700      int a = 0;      int a = 0;
701      if (k > move.pos) {      if (l > region->KeyRange.low) {
702          for (gig::Region* r = regions.first() ; ; r = regions.next()) {          for (gig::Region* r = regions.first() ; ; r = regions.next()) {
703              if (r != region) {              if (r != region) {
704                  int b = r ? r->KeyRange.low : 128;                  int b = r ? r->KeyRange.low : 128;
705    
706                  // gap: from a to b (not inclusive b)                  // gap: from a to b (not inclusive b)
707    
708                  if (region->KeyRange.high + move.pos >= b) {                  if (region->KeyRange.high >= b) {
709                      // not found the current gap yet, just continue                      // not found the current gap yet, just continue
710                  } else {                  } else {
711    
712                      if (a > region->KeyRange.low + k) {                      if (a > l) {
713                          // this gap is too far to the right, break                          // this gap is too far to the right, break
714                          break;                          break;
715                      }                      }
716    
717                      int newhigh = std::min(region->KeyRange.high + k, b - 1);                      int newhigh = std::min(l + regionsize, b - 1);
718                      int newlo = newhigh - (region->KeyRange.high - region->KeyRange.low);                      int newlo = newhigh - regionsize;
719    
720                      if (newlo >= a) {                      if (newlo >= a) {
721                          // yes it fits - it's a candidate                          // yes it fits - it's a candidate
722                          new_k = newlo - region->KeyRange.low;                          new_l = newlo;
                         new_touch_left = a > 0 && a == newlo;  
                         new_touch_right = b < 128 && newhigh + 1 == b;  
723                      }                      }
724                  }                  }
725                  if (!r) break;                  if (!r) break;
# Line 520  void RegionChooser::motion_move_region(i Line 733  void RegionChooser::motion_move_region(i
733    
734                  // gap from a to b (not inclusive b)                  // gap from a to b (not inclusive b)
735    
736                  if (region->KeyRange.high + k >= b) {                  if (l + regionsize >= b) {
737                      // not found the current gap yet, just continue                      // not found the current gap yet, just continue
738                  } else {                  } else {
739    
740                      if (a > region->KeyRange.low + move.pos) {                      if (a > region->KeyRange.low) {
741                          // this gap is too far to the right, break                          // this gap is too far to the right, break
742                          break;                          break;
743                      }                      }
744    
745                      int newlo = std::max(region->KeyRange.low + k, a);                      int newlo = std::max(l, a);
746                      int newhigh = newlo + (region->KeyRange.high - region->KeyRange.low);                      int newhigh = newlo + regionsize;
747    
748                      if (newhigh < b) {                      if (newhigh < b) {
749                          // yes it fits - break as the first one is the best                          // yes it fits - break as the first one is the best
750                          new_k = newlo - region->KeyRange.low;                          new_l = newlo;
                         new_touch_left = a > 0 && a == newlo;  
                         new_touch_right = b < 128 && newhigh + 1 == b;  
751                          break;                          break;
752                      }                      }
753                  }                  }
# Line 545  void RegionChooser::motion_move_region(i Line 756  void RegionChooser::motion_move_region(i
756              }              }
757          }          }
758      }      }
759      k = new_k;      if (new_l == region->KeyRange.low) return;
     if (k == move.pos) return;  
760    
761      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);
762      int prevx = int(w * (move.pos + region->KeyRange.low) / 128.0 + 0.5);      int x2 = key_to_x(std::max(int(region->KeyRange.high),
763      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);  
764    
765          window->draw_rectangle(gc, true, x + 1, 1, std::min(x2 - 1, prevx) - x, h1 - 2);      Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
766      }      update_after_move(new_l);
767    
768      move.pos = k;      get_window()->invalidate_rect(rect, false);
     move.touch_left = new_touch_left;  
     move.touch_right = new_touch_right;  
769  }  }
770    
771    
# Line 592  bool RegionChooser::on_motion_notify_eve Line 776  bool RegionChooser::on_motion_notify_eve
776      Gdk::ModifierType state = Gdk::ModifierType(0);      Gdk::ModifierType state = Gdk::ModifierType(0);
777      window->get_pointer(x, y, state);      window->get_pointer(x, y, state);
778    
779        // handle virtual MIDI keyboard
780        if (m_VirtKeybModeChoice.get_value() != VIRT_KEYBOARD_MODE_CHORD &&
781            currentActiveKey > 0 &&
782            event->y >= REGION_BLOCK_HEIGHT &&
783            event->y < REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT)
784        {
785            const int k = x_to_key(event->x, get_width() - 1);
786            if (k != currentActiveKey) {
787                int velocity =
788                    (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
789                    int(float(event->y - REGION_BLOCK_HEIGHT) /
790                        float(KEYBOARD_HEIGHT) * 128.0f) + 1;
791                if (velocity <= 0) velocity = 1;
792                keyboard_key_released_signal.emit(currentActiveKey, velocity);
793                currentActiveKey = k;
794                keyboard_key_hit_signal.emit(k, velocity);
795            }
796        }
797    
798      if (resize.active) {      if (resize.active) {
799          motion_resize_region(x, y);          motion_resize_region(x, y);
800      } else if (move.active) {      } else if (move.active) {
# Line 599  bool RegionChooser::on_motion_notify_eve Line 802  bool RegionChooser::on_motion_notify_eve
802      } else {      } else {
803          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
804              if (!cursor_is_resize) {              if (!cursor_is_resize) {
805    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
806                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
807    #else
808                    window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
809    #endif
810                  cursor_is_resize = true;                  cursor_is_resize = true;
811              }              }
812          } else if (cursor_is_resize) {          } else if (cursor_is_resize) {
# Line 620  bool RegionChooser::is_in_resize_zone(do Line 827  bool RegionChooser::is_in_resize_zone(do
827          for (gig::Region* r = regions.first(); r ; r = next_region) {          for (gig::Region* r = regions.first(); r ; r = next_region) {
828              next_region = regions.next();              next_region = regions.next();
829    
830              int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);              int lo = key_to_x(r->KeyRange.low, w);
831              if (x <= lo - 2) break;              if (x <= lo - 2) break;
832              if (x < lo + 2) {              if (x < lo + 2) {
833                  resize.region = r;                  resize.region = r;
# Line 643  bool RegionChooser::is_in_resize_zone(do Line 850  bool RegionChooser::is_in_resize_zone(do
850                  return resize.min != resize.max;                  return resize.min != resize.max;
851              }              }
852              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
853                  int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);                  int hi = key_to_x(r->KeyRange.high + 1, w);
854                  if (x <= hi - 2) break;                  if (x <= hi - 2) break;
855                  if (x < hi + 2) {                  if (x < hi + 2) {
856                      // edit high limit                      // edit high limit
# Line 674  sigc::signal<void>& RegionChooser::signa Line 881  sigc::signal<void>& RegionChooser::signa
881  void RegionChooser::show_region_properties()  void RegionChooser::show_region_properties()
882  {  {
883      if (!region) return;      if (!region) return;
884      Gtk::Dialog dialog("Region Properties", true /*modal*/);      Gtk::Dialog dialog(_("Region Properties"), true /*modal*/);
885      // add "Keygroup" checkbox      // add "Keygroup" checkbox
886      Gtk::CheckButton checkBoxKeygroup("Member of a Keygroup (Exclusive Group)");      Gtk::CheckButton checkBoxKeygroup(_("Member of a Keygroup (Exclusive Group)"));
887      checkBoxKeygroup.set_active(region->KeyGroup);      checkBoxKeygroup.set_active(region->KeyGroup);
888      dialog.get_vbox()->pack_start(checkBoxKeygroup);      dialog.get_vbox()->pack_start(checkBoxKeygroup);
889      checkBoxKeygroup.show();      checkBoxKeygroup.show();
890      // add "Keygroup" spinbox      // add "Keygroup" spinbox
891      Gtk::Adjustment adjustment(1, 1, pow(2,32));  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
892        Gtk::Adjustment adjustment(1, 1, 999);
893      Gtk::SpinButton spinBox(adjustment);      Gtk::SpinButton spinBox(adjustment);
894    #else
895        Gtk::SpinButton spinBox(Gtk::Adjustment::create(1, 1, 999));
896    #endif
897      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);
898      dialog.get_vbox()->pack_start(spinBox);      dialog.get_vbox()->pack_start(spinBox);
899      spinBox.show();      spinBox.show();
# Line 708  void RegionChooser::add_region() Line 919  void RegionChooser::add_region()
919    
920      queue_draw();      queue_draw();
921      region_selected();      region_selected();
922        dimensionManager.set_region(region);
923      instrument_changed();      instrument_changed();
924  }  }
925    
# Line 721  void RegionChooser::delete_region() Line 933  void RegionChooser::delete_region()
933      region = 0;      region = 0;
934      queue_draw();      queue_draw();
935      region_selected();      region_selected();
936        dimensionManager.set_region(region);
937      instrument_changed();      instrument_changed();
938  }  }
939    
# Line 751  sigc::signal<void, gig::Region*>& Region Line 964  sigc::signal<void, gig::Region*>& Region
964  sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {  sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {
965      return region_changed_signal;      return region_changed_signal;
966  }  }
967    
968    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_hit() {
969        return keyboard_key_hit_signal;
970    }
971    
972    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_released() {
973        return keyboard_key_released_signal;
974    }

Legend:
Removed from v.1658  
changed lines
  Added in v.2841

  ViewVC Help
Powered by ViewVC