/[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 1396 by schoenebeck, Wed Oct 10 15:48:54 2007 UTC revision 2246 by persson, Fri Aug 19 10:55:41 2011 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006, 2007 Andreas Persson   * Copyright (C) 2006-2011 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 18  Line 18 
18   */   */
19    
20  #include "regionchooser.h"  #include "regionchooser.h"
21    
22    #include <algorithm>
23    #include <sstream>
24    
25    #include <cairomm/context.h>
26    #include <gdkmm/general.h>
27  #include <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
28  #include <gtkmm/stock.h>  #include <gtkmm/stock.h>
29  #include <gtkmm/spinbutton.h>  #include <gtkmm/spinbutton.h>
30  #include <gtkmm/dialog.h>  #include <gtkmm/dialog.h>
 #include <math.h>  
31    
32  #include "global.h"  #include "global.h"
33    
34  RegionChooser::RegionChooser()  #define REGION_BLOCK_HEIGHT             20
35  {  #define KEYBOARD_HEIGHT                 40
36      Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();  
37    void SortedRegions::update(gig::Instrument* instrument) {
38        // Usually, the regions in a gig file are ordered after their key
39        // range, but there are files where they are not. The
40        // RegionChooser code needs a sorted list of regions.
41        regions.clear();
42        if (instrument) {
43            for (gig::Region* r = instrument->GetFirstRegion() ;
44                 r ;
45                 r = instrument->GetNextRegion()) {
46                regions.push_back(r);
47            }
48            sort(regions.begin(), regions.end(), *this);
49        }
50    }
51    
52    gig::Region* SortedRegions::first() {
53        region_iterator = regions.begin();
54        return region_iterator == regions.end() ? 0 : *region_iterator;
55    }
56    
57    gig::Region* SortedRegions::next() {
58        region_iterator++;
59        return region_iterator == regions.end() ? 0 : *region_iterator;
60    }
61    
62    
     red = Gdk::Color("#8070ff");  
     grey1 = Gdk::Color("#b0b0b0");  
63    
64      colormap->alloc_color(red);  RegionChooser::RegionChooser() :
65      colormap->alloc_color(grey1);      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        set_size_request(500, KEYBOARD_HEIGHT + REGION_BLOCK_HEIGHT);
74    
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      width = 800;  
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 89  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  }  }
159    
160  RegionChooser::~RegionChooser()  RegionChooser::~RegionChooser()
161  {  {
162  }  }
163    
164  void RegionChooser::on_realize()  template<class T> inline std::string ToString(T o) {
165  {      std::stringstream ss;
166      // We need to call the base on_realize()      ss << o;
167      Gtk::DrawingArea::on_realize();      return ss.str();
168    }
169    
170      // Now we can allocate any additional resources we need  void RegionChooser::invalidate_key(int key) {
171      Glib::RefPtr<Gdk::Window> window = get_window();      const int h = KEYBOARD_HEIGHT;
172      gc = Gdk::GC::create(window);      const int w = get_width() - 1;
173      window->clear();      int x1 = key_to_x(key - 0.5, w);
174        int x2 = key_to_x(key + 1.5, w);
175    
176        Gdk::Rectangle rect(x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);
177        get_window()->invalidate_rect(rect, false);
178  }  }
179    
180  bool RegionChooser::on_expose_event(GdkEventExpose* event)  void RegionChooser::on_note_on_event(int key, int velocity) {
181  {      key_pressed[key] = true;
182      Glib::RefPtr<Gdk::Window> window = get_window();      invalidate_key(key);
183      window->clear();      m_VirtKeybVelocityLabel.set_text(ToString(velocity));
184      const int h = 40;  }
     const int w = width - 1;  
     const int bh = int(h * 0.55);  
185    
186      Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();  void RegionChooser::on_note_off_event(int key, int velocity) {
187      Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();      key_pressed[key] = false;
188        invalidate_key(key);
189        m_VirtKeybOffVelocityLabel.set_text(ToString(velocity));
190    }
191    
     Glib::RefPtr<Pango::Context> context = get_pango_context();  
     Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);  
192    
193      window->draw_rectangle(black, false, 0, h1, w, h - 1);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
194      gc->set_foreground(grey1);  bool RegionChooser::on_expose_event(GdkEventExpose* e) {
195      int x1 = int(w * 20.5 / 128.0 + 0.5);      double clipx1 = e->area.x;
196      int x2 = int(w * 109.5 / 128.0 + 0.5);      double clipx2 = e->area.x + e->area.width;
197      window->draw_rectangle(gc, true, 1, h1 + 1,      double clipy1 = e->area.y;
198                             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);  
199    
200          if (note == 1 || note == 4 || note == 6 || note == 9 || note == 11) {      const Cairo::RefPtr<Cairo::Context>& cr =
201              int x2 = int(w * (i + 0.5) / 128.0 + 0.5);          get_window()->create_cairo_context();
202              window->draw_line(black, x2, h1 + bh, x2, h1 + h);  #if 0
203    }
204    #endif
205    #else
206    bool RegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) {
207        double clipx1, clipx2, clipy1, clipy2;
208        cr->get_clip_extents(clipx1, clipy1, clipx2, clipy2);
209    #endif
210    
211              int x3 = int(w * (i + 1) / 128.0 + 0.5);      cr->save();
212              window->draw_rectangle(black, true, x, h1 + 1, x3 - x + 1, bh);      cr->set_line_width(1);
         } else if (note == 3 || note == 8) {  
             window->draw_line(black, x, h1 + 1, x, h1 + h);  
         }  
         if (note == 3) {  
             char buf[30];  
             sprintf(buf, "<span size=\"x-small\">%d</span>", octave);  
             layout->set_markup(buf);  
             Pango::Rectangle rectangle = layout->get_logical_extents();  
             double text_w = double(rectangle.get_width()) / Pango::SCALE;  
             double text_h = double(rectangle.get_height()) / Pango::SCALE;  
             double x2 = w * (i + 0.75) / 128.0;  
             window->draw_layout(black, int(x2 - text_w / 2 + 1),  
                                 int(h1 + h - text_h + 0.5), layout);  
             octave++;  
         }  
     }  
213    
214      if (instrument) {  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
215          int i = 0;      const Gdk::Color bg = get_style()->get_bg(Gtk::STATE_NORMAL);
216          gig::Region *next_region;  #else
217          int x3 = -1;      const Gdk::RGBA bg = get_style_context()->get_background_color();
218          for (gig::Region *r = instrument->GetFirstRegion() ;  #endif
219               r ;      Gdk::Cairo::set_source_rgba(cr, bg);
220               r = next_region) {      cr->paint();
221    
222              if (x3 < 0) x3 = int(w * (r->KeyRange.low) / 128.0 + 0.5);      const int w = get_width() - 1;
             next_region = instrument->GetNextRegion();  
             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++;  
         }  
223    
224          for (gig::Region *r = instrument->GetFirstRegion() ;      if (clipy2 > h1) {
225               r ;          draw_keyboard(cr, clipx1, clipx2);
226               r = instrument->GetNextRegion()) {      }
             int x = int(w * (r->KeyRange.low) / 128.0 + 0.5);  
             window->draw_line(black, x, 1, x, h1 - 2);  
         }  
227    
228          if (region) {      if (clipy1 < h1 && instrument) {
229              int x1 = int(w * (region->KeyRange.low) / 128.0 + 0.5);          draw_regions(cr, clipx1, clipx2);
             int x2 = int(w * (region->KeyRange.high + 1) / 128.0 + 0.5);  
             gc->set_foreground(red);  
             window->draw_rectangle(gc, true, x1 + 1, 1, x2 - x1 - 1, h1 - 2);  
         }  
230      }      }
231    
232        cr->restore();
233    
234      return true;      return true;
235  }  }
236    
237    void RegionChooser::draw_keyboard(const Cairo::RefPtr<Cairo::Context>& cr,
238                                      int clip_low, int clip_high) {
239        const int h = KEYBOARD_HEIGHT;
240        const int w = get_width() - 1;
241        const int bh = int(h * 0.55);
242    
243  void RegionChooser::on_size_request(GtkRequisition* requisition)      Gdk::Cairo::set_source_rgba(cr, black);
244  {      cr->rectangle(0.5, h1 + 0.5, w, h - 1);
245      *requisition = GtkRequisition();      cr->stroke();
246      requisition->height = 40 + 20;  
247      requisition->width = 500;      int x1 = key_to_x(20.5, w);
248        Gdk::Cairo::set_source_rgba(cr, grey1);
249        cr->rectangle(1, h1 + 1, x1 - 1, h - 2);
250        cr->fill();
251    
252        int x2 = key_to_x(109.5, w);
253        Gdk::Cairo::set_source_rgba(cr, white);
254        cr->rectangle(x1 + 1, h1 + 1, x2 - x1 - 1, h - 2);
255        cr->fill();
256    
257        Gdk::Cairo::set_source_rgba(cr, grey1);
258        cr->rectangle(x2 + 1, h1 + 1, w - x2 - 1, h - 2);
259        cr->fill();
260    
261        Gdk::Cairo::set_source_rgba(cr, black);
262    
263        int clipkey1 = std::max(0, x_to_key_right(clip_low - 1, w));
264        int clipkey2 = std::min(x_to_key_right(clip_high - 1, w) + 1, 128);
265    
266        for (int i = clipkey1 ; i < clipkey2 ; i++) {
267            int note = (i + 3) % 12;
268            int x = key_to_x(i, w);
269    
270            if (note == 1 || note == 4 || note == 6 ||
271                note == 9 || note == 11) {
272                // black key: short line in the middle, with a rectangle
273                // on top
274                int x2 = key_to_x(i + 0.5, w);
275                cr->move_to(x2 + 0.5, h1 + bh + 0.5);
276                cr->line_to(x2 + 0.5, h1 + h - 1);
277                cr->stroke();
278    
279                int x3 = key_to_x(i + 1, w);
280                cr->rectangle(x, h1 + 1, x3 - x + 1, bh);
281                cr->fill();
282            } else if (note == 3 || note == 8) {
283                // C or F: long line to the left
284                cr->move_to(x + 0.5, h1 + 1);
285                cr->line_to(x + 0.5, h1 + h - 1);
286                cr->stroke();
287            }
288    
289            if (key_pressed[i]) draw_key(cr, i);
290    
291            if (note == 3) draw_digit(cr, i);
292        }
293  }  }
294    
295    
296  // not used  void RegionChooser::draw_regions(const Cairo::RefPtr<Cairo::Context>& cr,
297  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)                                   int clip_low, int clip_high) {
298  {      const int w = get_width() - 1;
299      const int h = 40;  
300      const int w = width;      Gdk::Cairo::set_source_rgba(cr, black);
301        gig::Region* next_region;
302        int x3 = -1;
303        for (gig::Region* r = regions.first() ; r ; r = next_region) {
304            next_region = regions.next();
305    
306            if (x3 < 0) {
307                x3 = key_to_x(r->KeyRange.low, w);
308                if (x3 >= clip_high) break;
309            }
310            if (!next_region ||
311                r->KeyRange.high + 1 != next_region->KeyRange.low ||
312                r == region || next_region == region) {
313    
314                int x2 = key_to_x(r->KeyRange.high + 1, w);
315                if (x2 >= clip_low) {
316                    cr->move_to(x3, 0.5);
317                    cr->line_to(x2 + 0.5, 0.5);
318                    cr->line_to(x2 + 0.5, h1 - 0.5);
319                    cr->line_to(x3, h1 - 0.5);
320                    cr->stroke();
321    
322                    Gdk::Cairo::set_source_rgba(cr, region == r ? red : white);
323                    cr->rectangle(x3 + 1, 1, x2 - x3 - 1, h1 - 2);
324                    cr->fill();
325                    Gdk::Cairo::set_source_rgba(cr, black);
326                }
327                x3 = -1;
328            }
329        }
330    
331        for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
332            int x = key_to_x(r->KeyRange.low, w);
333    
334            if (x < clip_low) continue;
335            if (x >= clip_high) break;
336    
337            cr->move_to(x + 0.5, 1);
338            cr->line_to(x + 0.5, h1 - 1);
339            cr->stroke();
340        }
341    }
342    
343    bool RegionChooser::is_black_key(int key) {
344        const int note = (key + 3) % 12;
345        return note == 1 || note == 4 || note == 6 || note == 9 || note == 11;
346    }
347    
348    void RegionChooser::draw_digit(const Cairo::RefPtr<Cairo::Context>& cr,
349                                   int key) {
350        const int h = KEYBOARD_HEIGHT;
351        const int w = get_width() - 1;
352        Glib::RefPtr<Pango::Layout> layout =
353            Pango::Layout::create(get_pango_context());
354        char buf[30];
355        sprintf(buf, "<span size=\"8000\">%d</span>", key / 12 - 1);
356        layout->set_markup(buf);
357        Pango::Rectangle rectangle = layout->get_logical_extents();
358        double text_w = double(rectangle.get_width()) / Pango::SCALE;
359        double text_h = double(rectangle.get_height()) / Pango::SCALE;
360        double x = w * (key + 0.75) / 128.0;
361        Gdk::Cairo::set_source_rgba(cr, black);
362        cr->move_to(int(x - text_w / 2 + 1), int(h1 + h - text_h + 0.5));
363    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
364        pango_cairo_show_layout(cr->cobj(), layout->gobj());
365    #else
366        layout->show_in_cairo_context(cr);
367    #endif
368    }
369    
370    void RegionChooser::draw_key(const Cairo::RefPtr<Cairo::Context>& cr,
371                                 int key) {
372        const int h = KEYBOARD_HEIGHT;
373        const int w = get_width() - 1;
374      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
375    
376      Glib::RefPtr<Gdk::Window> window = get_window();      Gdk::Cairo::set_source_rgba(cr, activeKeyColor);
     gc->set_foreground(color);  
377    
378      for (int i = from ; i < to ; i++) {      int note = (key + 3) % 12;
379          int note = (i + 3) % 12;      int x = key_to_x(key, w) + 1;
380          int x = int(w * i / 128.0 + 0.5) + 1;      int x2 = key_to_x(key + 1.5, w);
381          int x2 = int(w * (i + 1.5) / 128.0 + 0.5);      int x3 = key_to_x(key + 1, w);
382          int x3 = int(w * (i + 1) / 128.0 + 0.5);      int x4 = key_to_x(key - 0.5, w);
383          int x4 = int(w * (i - 0.5) / 128 + 0.5) + 1;      int w1 = x3 - x;
384          int w1 = x3 - x;      switch (note) {
385          switch (note) {      case 0: case 5: case 10:
386          case 0: case 5: case 10:          cr->rectangle(x, h1 + 1, w1, bh);
387              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);          cr->fill();
388              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);
389              break;          cr->fill();
390          case 2: case 7:          break;
391              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);      case 2: case 7:
392              window->draw_rectangle(gc, true, x4, h1 + bh + 1, x3 - x4, h - bh - 2);          cr->rectangle(x, h1 + 1, w1, bh);
393              break;          cr->fill();
394          case 3: case 8:          cr->rectangle(x4 + 1, h1 + bh + 1, x3 - x4 - 1, h - bh - 2);
395              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);          cr->fill();
396              window->draw_rectangle(gc, true, x, h1 + bh + 1, x2 - x, h - bh - 2);          break;
397              break;      case 3: case 8:
398          default:          cr->rectangle(x, h1 + 1, w1, bh);
399              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh - 1);          cr->fill();
400              break;          cr->rectangle(x, h1 + bh + 1, x2 - x, h - bh - 2);
401          }          cr->fill();
402            break;
403        default:
404            cr->rectangle(x, h1 + 1, w1, bh - 1);
405            cr->fill();
406            break;
407      }      }
408        Gdk::Cairo::set_source_rgba(cr, black);
409  }  }
410    
411  void RegionChooser::set_instrument(gig::Instrument* instrument)  void RegionChooser::set_instrument(gig::Instrument* instrument)
412  {  {
413      this->instrument = instrument;      this->instrument = instrument;
414      region = instrument ? instrument->GetFirstRegion() : 0;      regions.update(instrument);
415        region = regions.first();
416      queue_draw();      queue_draw();
417      region_selected();      region_selected();
418        dimensionManager.set_region(region);
419  }  }
420    
421  bool RegionChooser::on_button_release_event(GdkEventButton* event)  bool RegionChooser::on_button_release_event(GdkEventButton* event)
422  {  {
423        const int k = x_to_key(event->x, get_width() - 1);
424    
425        // handle-note off on virtual keyboard
426        if (event->type == GDK_BUTTON_RELEASE) {
427            int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
428                           int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
429            if (velocity <= 0) velocity = 1;
430            switch (m_VirtKeybModeChoice.get_value()) {
431                case VIRT_KEYBOARD_MODE_CHORD:
432                    if (event->y >= REGION_BLOCK_HEIGHT)
433                        keyboard_key_released_signal.emit(k, velocity);
434                    break;
435                case VIRT_KEYBOARD_MODE_NORMAL:
436                default:
437                    if (currentActiveKey >= 0 && currentActiveKey <= 127) {
438                        keyboard_key_released_signal.emit(currentActiveKey, velocity);
439                        currentActiveKey = -1;
440                    }
441                    break;
442            }
443        }
444    
445      if (resize.active) {      if (resize.active) {
446    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
447          get_window()->pointer_ungrab(event->time);          get_window()->pointer_ungrab(event->time);
448    #else
449            Glib::wrap(event->device, true)->ungrab(event->time);
450    #endif
451          resize.active = false;          resize.active = false;
452    
         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  
                 );  
                 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  
                 );  
                 instrument_changed.emit();  
                 instrument_struct_changed_signal.emit(instrument);  
             }  
         }  
   
453          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
454              get_window()->set_cursor();              get_window()->set_cursor();
455              cursor_is_resize = false;              cursor_is_resize = false;
456          }          }
457      } else if (move.active) {      } else if (move.active) {
458    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
459          get_window()->pointer_ungrab(event->time);          get_window()->pointer_ungrab(event->time);
460    #else
461            Glib::wrap(event->device, true)->ungrab(event->time);
462    #endif
463          move.active = false;          move.active = false;
464    
         if (move.pos) {  
             instrument_struct_to_be_changed_signal.emit(instrument);  
             region->SetKeyRange(  
                 region->KeyRange.low  + move.pos,  
                 region->KeyRange.high + move.pos  
             );  
             instrument_struct_changed_signal.emit(instrument);  
         }  
   
465          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
466    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
467              get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));              get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
468    #else
469                get_window()->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
470    #endif
471              cursor_is_resize = true;              cursor_is_resize = true;
472          }          }
473      }      }
474      return true;      return true;
475  }  }
476    
477    void RegionChooser::update_after_resize()
478    {
479        if (resize.mode == resize.moving_high_limit) {
480            if (resize.region->KeyRange.high != resize.pos - 1) {
481                instrument_struct_to_be_changed_signal.emit(instrument);
482                resize.region->SetKeyRange(resize.region->KeyRange.low,
483                                           resize.pos - 1);
484                regions.update(instrument);
485                instrument_changed.emit();
486                instrument_struct_changed_signal.emit(instrument);
487            }
488        } else if (resize.mode == resize.moving_low_limit) {
489            if (resize.region->KeyRange.low != resize.pos) {
490                instrument_struct_to_be_changed_signal.emit(instrument);
491                resize.region->SetKeyRange(resize.pos,
492                                           resize.region->KeyRange.high);
493                regions.update(instrument);
494                instrument_changed.emit();
495                instrument_struct_changed_signal.emit(instrument);
496            }
497        }
498    }
499    
500    void RegionChooser::update_after_move(int pos)
501    {
502        instrument_struct_to_be_changed_signal.emit(instrument);
503        region->SetKeyRange(pos, pos + region->KeyRange.high -
504                            region->KeyRange.low);
505        regions.update(instrument);
506        instrument_changed.emit();
507        instrument_struct_changed_signal.emit(instrument);
508    }
509    
510  bool RegionChooser::on_button_press_event(GdkEventButton* event)  bool RegionChooser::on_button_press_event(GdkEventButton* event)
511  {  {
512      if (!instrument) return true;      if (!instrument) return true;
513    
514      int k = int(event->x / (width - 1) * 128.0);      const int w = get_width() - 1;
515        const int k = x_to_key(event->x, w);
516    
517        if (event->type == GDK_BUTTON_PRESS) {
518            if (event->y >= REGION_BLOCK_HEIGHT) {
519                int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
520                               int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
521                currentActiveKey = k;
522                keyboard_key_hit_signal.emit(k, velocity);
523            }
524        }
525    
526        if (event->y >= REGION_BLOCK_HEIGHT) return true;
527      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
528          gig::Region* r = get_region(k);          gig::Region* r = get_region(k);
529          if (r) {          if (r) {
530              region = r;              region = r;
531              queue_draw();              queue_draw();
532              region_selected();              region_selected();
533                dimensionManager.set_region(region);
534              popup_menu_inside_region->popup(event->button, event->time);              popup_menu_inside_region->popup(event->button, event->time);
535          } else {          } else {
536              new_region_pos = k;              new_region_pos = k;
# Line 321  bool RegionChooser::on_button_press_even Line 538  bool RegionChooser::on_button_press_even
538          }          }
539      } else {      } else {
540          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
541    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
542              get_window()->pointer_grab(false,              get_window()->pointer_grab(false,
543                                         Gdk::BUTTON_RELEASE_MASK |                                         Gdk::BUTTON_RELEASE_MASK |
544                                         Gdk::POINTER_MOTION_MASK |                                         Gdk::POINTER_MOTION_MASK |
545                                         Gdk::POINTER_MOTION_HINT_MASK,                                         Gdk::POINTER_MOTION_HINT_MASK,
546                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW), event->time);                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW),
547                                           event->time);
548    #else
549                Glib::wrap(event->device, true)->grab(get_window(),
550                                                      Gdk::OWNERSHIP_NONE,
551                                                      false,
552                                                      Gdk::BUTTON_RELEASE_MASK |
553                                                      Gdk::POINTER_MOTION_MASK |
554                                                      Gdk::POINTER_MOTION_HINT_MASK,
555                                                      Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW),
556                                                      event->time);
557    #endif
558              resize.active = true;              resize.active = true;
559          } else {          } else {
560              gig::Region* r = get_region(k);              gig::Region* r = get_region(k);
# Line 333  bool RegionChooser::on_button_press_even Line 562  bool RegionChooser::on_button_press_even
562                  region = r;                  region = r;
563                  queue_draw();                  queue_draw();
564                  region_selected();                  region_selected();
565                    dimensionManager.set_region(region);
566    
567    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
568                  get_window()->pointer_grab(false,                  get_window()->pointer_grab(false,
569                                             Gdk::BUTTON_RELEASE_MASK |                                             Gdk::BUTTON_RELEASE_MASK |
570                                             Gdk::POINTER_MOTION_MASK |                                             Gdk::POINTER_MOTION_MASK |
571                                             Gdk::POINTER_MOTION_HINT_MASK,                                             Gdk::POINTER_MOTION_HINT_MASK,
572                                             Gdk::Cursor(Gdk::FLEUR), event->time);                                             Gdk::Cursor(Gdk::FLEUR),
573                                               event->time);
574    #else
575                    Glib::wrap(event->device, true)->grab(get_window(),
576                                                          Gdk::OWNERSHIP_NONE,
577                                                          false,
578                                                          Gdk::BUTTON_RELEASE_MASK |
579                                                          Gdk::POINTER_MOTION_MASK |
580                                                          Gdk::POINTER_MOTION_HINT_MASK,
581                                                          Gdk::Cursor::create(Gdk::FLEUR),
582                                                          event->time);
583    #endif
584                  move.active = true;                  move.active = true;
585                  move.from_x = event->x;                  move.offset = event->x - key_to_x(region->KeyRange.low, w);
                 move.pos = 0;  
586              }              }
587          }          }
588      }      }
# Line 350  bool RegionChooser::on_button_press_even Line 591  bool RegionChooser::on_button_press_even
591    
592  gig::Region* RegionChooser::get_region(int key)  gig::Region* RegionChooser::get_region(int key)
593  {  {
594      gig::Region* prev_region = 0;      for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
     gig::Region* next_region;  
     for (gig::Region *r = instrument->GetFirstRegion() ; r ;  
          r = next_region) {  
         next_region = instrument->GetNextRegion();  
   
595          if (key < r->KeyRange.low) return 0;          if (key < r->KeyRange.low) return 0;
596          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;  
597      }      }
598      return 0;      return 0;
599  }  }
600    
601  void RegionChooser::motion_resize_region(int x, int y)  void RegionChooser::motion_resize_region(int x, int y)
602  {  {
603      const int w = width - 1;      const int w = get_width() - 1;
     Glib::RefPtr<Gdk::Window> window = get_window();  
604    
605      int k = int(double(x) / w * 128.0 + 0.5);      int k = int(double(x) / w * 128.0 + 0.5);
606    
# Line 390  void RegionChooser::motion_resize_region Line 620  void RegionChooser::motion_resize_region
620                  resize.mode = resize.moving_low_limit;                  resize.mode = resize.moving_low_limit;
621              }              }
622          }          }
623          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);  
624    
625            int x1, x2;
626          if (resize.mode == resize.moving_high_limit) {          if (resize.mode == resize.moving_high_limit) {
627              if (k > resize.pos) {              if (resize.region->KeyRange.high < resize.pos - 1) {
628                  window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);                  x1 = resize.region->KeyRange.high;
629                  window->draw_line(black, prevx, 0, x, 0);                  x2 = resize.pos - 1;
                 window->draw_line(black, prevx, h1 - 1, x, h1 - 1);  
630              } else {              } else {
631                  int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);                  x1 = resize.pos - 1;
632                  window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);                  x2 = resize.region->KeyRange.high;
633              }              }
634          } else {          } else {
635              if (k < resize.pos) {              if (resize.region->KeyRange.low < resize.pos) {
636                  window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);                  x1 = resize.region->KeyRange.low;
637                  window->draw_line(black, x, 0, prevx, 0);                  x2 = resize.pos;
                 window->draw_line(black, x, h1 - 1, prevx, h1 - 1);  
638              } else {              } else {
639                  int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);                  x1 = resize.pos;
640                  window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);                  x2 = resize.region->KeyRange.low;
641              }              }
642          }          }
643          window->draw_line(black, x, 1, x, h1 - 2);          x1 = key_to_x(x1, w);
644          resize.pos = k;          x2 = key_to_x(x2 + 1, w) + 1;
645            Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
646    
647            update_after_resize();
648    
649            get_window()->invalidate_rect(rect, false);
650      }      }
651  }  }
652    
653  void RegionChooser::motion_move_region(int x, int y)  void RegionChooser::motion_move_region(int x, int y)
654  {  {
655      const int w = width - 1;      const int w = get_width() - 1;
     Glib::RefPtr<Gdk::Window> window = get_window();  
656    
657      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);
658      if (k == move.pos) return;  
659      int new_k;      if (l == region->KeyRange.low) return;
660      bool new_touch_left;      int new_l;
661      bool new_touch_right;      int regionsize = region->KeyRange.high - region->KeyRange.low;
662      int a = 0;      int a = 0;
663      if (k > move.pos) {      if (l > region->KeyRange.low) {
664          for (gig::Region* r = instrument->GetFirstRegion() ; ;          for (gig::Region* r = regions.first() ; ; r = regions.next()) {
              r = instrument->GetNextRegion()) {  
665              if (r != region) {              if (r != region) {
666                  int b = r ? r->KeyRange.low : 128;                  int b = r ? r->KeyRange.low : 128;
667    
668                  // gap: from a to b (not inclusive b)                  // gap: from a to b (not inclusive b)
669    
670                  if (region->KeyRange.high + move.pos >= b) {                  if (region->KeyRange.high >= b) {
671                      // not found the current gap yet, just continue                      // not found the current gap yet, just continue
672                  } else {                  } else {
673    
674                      if (a > region->KeyRange.low + k) {                      if (a > l) {
675                          // this gap is too far to the right, break                          // this gap is too far to the right, break
676                          break;                          break;
677                      }                      }
678    
679                      int newhigh = std::min(region->KeyRange.high + k, b - 1);                      int newhigh = std::min(l + regionsize, b - 1);
680                      int newlo = newhigh - (region->KeyRange.high - region->KeyRange.low);                      int newlo = newhigh - regionsize;
681    
682                      if (newlo >= a) {                      if (newlo >= a) {
683                          // yes it fits - it's a candidate                          // yes it fits - it's a candidate
684                          new_k = newlo - region->KeyRange.low;                          new_l = newlo;
                         new_touch_left = a > 0 && a == newlo;  
                         new_touch_right = b < 128 && newhigh + 1 == b;  
685                      }                      }
686                  }                  }
687                  if (!r) break;                  if (!r) break;
# Line 467  void RegionChooser::motion_move_region(i Line 689  void RegionChooser::motion_move_region(i
689              }              }
690          }          }
691      } else {      } else {
692          for (gig::Region* r = instrument->GetFirstRegion() ; ;          for (gig::Region* r = regions.first() ; ; r = regions.next()) {
              r = instrument->GetNextRegion()) {  
693              if (r != region) {              if (r != region) {
694                  int b = r ? r->KeyRange.low : 128;                  int b = r ? r->KeyRange.low : 128;
695    
696                  // gap from a to b (not inclusive b)                  // gap from a to b (not inclusive b)
697    
698                  if (region->KeyRange.high + k >= b) {                  if (l + regionsize >= b) {
699                      // not found the current gap yet, just continue                      // not found the current gap yet, just continue
700                  } else {                  } else {
701    
702                      if (a > region->KeyRange.low + move.pos) {                      if (a > region->KeyRange.low) {
703                          // this gap is too far to the right, break                          // this gap is too far to the right, break
704                          break;                          break;
705                      }                      }
706    
707                      int newlo = std::max(region->KeyRange.low + k, a);                      int newlo = std::max(l, a);
708                      int newhigh = newlo + (region->KeyRange.high - region->KeyRange.low);                      int newhigh = newlo + regionsize;
709    
710                      if (newhigh < b) {                      if (newhigh < b) {
711                          // yes it fits - break as the first one is the best                          // yes it fits - break as the first one is the best
712                          new_k = newlo - region->KeyRange.low;                          new_l = newlo;
                         new_touch_left = a > 0 && a == newlo;  
                         new_touch_right = b < 128 && newhigh + 1 == b;  
713                          break;                          break;
714                      }                      }
715                  }                  }
# Line 499  void RegionChooser::motion_move_region(i Line 718  void RegionChooser::motion_move_region(i
718              }              }
719          }          }
720      }      }
721      k = new_k;      if (new_l == region->KeyRange.low) return;
     if (k == move.pos) return;  
   
     Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);  
     int prevx = int(w * (move.pos + region->KeyRange.low) / 128.0 + 0.5);  
     x = int(w * (k + region->KeyRange.low) / 128.0 + 0.5);  
     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);  
722    
723          window->draw_line(black, x, 0, std::min(x2, prevx - 1), 0);      int x1 = key_to_x(std::min(int(region->KeyRange.low), new_l), w);
724          window->draw_line(black, x, h1 - 1, std::min(x2, prevx - 1), h1 - 1);      int x2 = key_to_x(std::max(int(region->KeyRange.high),
725                                   new_l + regionsize) + 1, w) + 1;
726    
727          window->draw_rectangle(gc, true, x + 1, 1, std::min(x2 - 1, prevx) - x, h1 - 2);      Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
728      }      update_after_move(new_l);
729    
730      move.pos = k;      get_window()->invalidate_rect(rect, false);
     move.touch_left = new_touch_left;  
     move.touch_right = new_touch_right;  
731  }  }
732    
733    
# Line 546  bool RegionChooser::on_motion_notify_eve Line 738  bool RegionChooser::on_motion_notify_eve
738      Gdk::ModifierType state = Gdk::ModifierType(0);      Gdk::ModifierType state = Gdk::ModifierType(0);
739      window->get_pointer(x, y, state);      window->get_pointer(x, y, state);
740    
741        // handle virtual MIDI keyboard
742        if (m_VirtKeybModeChoice.get_value() != VIRT_KEYBOARD_MODE_CHORD &&
743            currentActiveKey > 0 &&
744            event->y >= REGION_BLOCK_HEIGHT &&
745            event->y < REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT)
746        {
747            const int k = x_to_key(event->x, get_width() - 1);
748            if (k != currentActiveKey) {
749                int velocity =
750                    (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
751                    int(float(event->y - REGION_BLOCK_HEIGHT) /
752                        float(KEYBOARD_HEIGHT) * 128.0f) + 1;
753                if (velocity <= 0) velocity = 1;
754                keyboard_key_released_signal.emit(currentActiveKey, velocity);
755                currentActiveKey = k;
756                keyboard_key_hit_signal.emit(k, velocity);
757            }
758        }
759    
760      if (resize.active) {      if (resize.active) {
761          motion_resize_region(x, y);          motion_resize_region(x, y);
762      } else if (move.active) {      } else if (move.active) {
# Line 553  bool RegionChooser::on_motion_notify_eve Line 764  bool RegionChooser::on_motion_notify_eve
764      } else {      } else {
765          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
766              if (!cursor_is_resize) {              if (!cursor_is_resize) {
767    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
768                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
769    #else
770                    window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
771    #endif
772                  cursor_is_resize = true;                  cursor_is_resize = true;
773              }              }
774          } else if (cursor_is_resize) {          } else if (cursor_is_resize) {
# Line 566  bool RegionChooser::on_motion_notify_eve Line 781  bool RegionChooser::on_motion_notify_eve
781  }  }
782    
783  bool RegionChooser::is_in_resize_zone(double x, double y) {  bool RegionChooser::is_in_resize_zone(double x, double y) {
784      const int w = width - 1;      const int w = get_width() - 1;
785    
786      if (instrument && y >= 0 && y <= h1) {      if (instrument && y >= 0 && y <= h1) {
787          gig::Region* prev_region = 0;          gig::Region* prev_region = 0;
788          gig::Region* next_region;          gig::Region* next_region;
789          for (gig::Region* r = instrument->GetFirstRegion() ; r ; r = next_region) {          for (gig::Region* r = regions.first(); r ; r = next_region) {
790              next_region = instrument->GetNextRegion();              next_region = regions.next();
791    
792              int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);              int lo = key_to_x(r->KeyRange.low, w);
793              if (x <= lo - 2) break;              if (x <= lo - 2) break;
794              if (x < lo + 2) {              if (x < lo + 2) {
795                  resize.region = r;                  resize.region = r;
# Line 588  bool RegionChooser::is_in_resize_zone(do Line 803  bool RegionChooser::is_in_resize_zone(do
803                      resize.mode = resize.undecided;                      resize.mode = resize.undecided;
804                      resize.min = prev_region->KeyRange.low + 1;                      resize.min = prev_region->KeyRange.low + 1;
805                      resize.prev_region = prev_region;                      resize.prev_region = prev_region;
806                      return true;                      return resize.min != resize.max;
807                  }                  }
808    
809                  // edit low limit                  // edit low limit
810                  resize.mode = resize.moving_low_limit;                  resize.mode = resize.moving_low_limit;
811                  resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;                  resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;
812                  return true;                  return resize.min != resize.max;
813              }              }
814              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
815                  int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);                  int hi = key_to_x(r->KeyRange.high + 1, w);
816                  if (x <= hi - 2) break;                  if (x <= hi - 2) break;
817                  if (x < hi + 2) {                  if (x < hi + 2) {
818                      // edit high limit                      // edit high limit
# Line 606  bool RegionChooser::is_in_resize_zone(do Line 821  bool RegionChooser::is_in_resize_zone(do
821                      resize.mode = resize.moving_high_limit;                      resize.mode = resize.moving_high_limit;
822                      resize.min = r->KeyRange.low + 1;                      resize.min = r->KeyRange.low + 1;
823                      resize.max = next_region ? next_region->KeyRange.low : 128;                      resize.max = next_region ? next_region->KeyRange.low : 128;
824                      return true;                      return resize.min != resize.max;
825                  }                  }
826              }              }
827              prev_region = r;              prev_region = r;
# Line 628  sigc::signal<void>& RegionChooser::signa Line 843  sigc::signal<void>& RegionChooser::signa
843  void RegionChooser::show_region_properties()  void RegionChooser::show_region_properties()
844  {  {
845      if (!region) return;      if (!region) return;
846      Gtk::Dialog dialog("Region Properties", true /*modal*/);      Gtk::Dialog dialog(_("Region Properties"), true /*modal*/);
847      // add "Keygroup" checkbox      // add "Keygroup" checkbox
848      Gtk::CheckButton checkBoxKeygroup("Member of a Keygroup (Exclusive Group)");      Gtk::CheckButton checkBoxKeygroup(_("Member of a Keygroup (Exclusive Group)"));
849      checkBoxKeygroup.set_active(region->KeyGroup);      checkBoxKeygroup.set_active(region->KeyGroup);
850      dialog.get_vbox()->pack_start(checkBoxKeygroup);      dialog.get_vbox()->pack_start(checkBoxKeygroup);
851      checkBoxKeygroup.show();      checkBoxKeygroup.show();
852      // add "Keygroup" spinbox      // add "Keygroup" spinbox
853      Gtk::Adjustment adjustment(1, 1, pow(2,32));  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
854        Gtk::Adjustment adjustment(1, 1, 999);
855      Gtk::SpinButton spinBox(adjustment);      Gtk::SpinButton spinBox(adjustment);
856    #else
857        Gtk::SpinButton spinBox(Gtk::Adjustment::create(1, 1, 999));
858    #endif
859      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);
860      dialog.get_vbox()->pack_start(spinBox);      dialog.get_vbox()->pack_start(spinBox);
861      spinBox.show();      spinBox.show();
# Line 658  void RegionChooser::add_region() Line 877  void RegionChooser::add_region()
877      region->SetKeyRange(new_region_pos, new_region_pos);      region->SetKeyRange(new_region_pos, new_region_pos);
878    
879      instrument_struct_changed_signal.emit(instrument);      instrument_struct_changed_signal.emit(instrument);
880        regions.update(instrument);
881    
882      queue_draw();      queue_draw();
883      region_selected();      region_selected();
884        dimensionManager.set_region(region);
885      instrument_changed();      instrument_changed();
886  }  }
887    
# Line 669  void RegionChooser::delete_region() Line 890  void RegionChooser::delete_region()
890      instrument_struct_to_be_changed_signal.emit(instrument);      instrument_struct_to_be_changed_signal.emit(instrument);
891      instrument->DeleteRegion(region);      instrument->DeleteRegion(region);
892      instrument_struct_changed_signal.emit(instrument);      instrument_struct_changed_signal.emit(instrument);
893        regions.update(instrument);
894    
895      region = 0;      region = 0;
896      queue_draw();      queue_draw();
897      region_selected();      region_selected();
898        dimensionManager.set_region(region);
899      instrument_changed();      instrument_changed();
900  }  }
901    
# Line 703  sigc::signal<void, gig::Region*>& Region Line 926  sigc::signal<void, gig::Region*>& Region
926  sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {  sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {
927      return region_changed_signal;      return region_changed_signal;
928  }  }
929    
930    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_hit() {
931        return keyboard_key_hit_signal;
932    }
933    
934    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_released() {
935        return keyboard_key_released_signal;
936    }

Legend:
Removed from v.1396  
changed lines
  Added in v.2246

  ViewVC Help
Powered by ViewVC