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

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

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

revision 1261 by persson, Thu Jul 5 17:12:20 2007 UTC revision 2773 by schoenebeck, Fri Jun 12 17:57:52 2015 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006, 2007 Andreas Persson   * Copyright (C) 2006-2015 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 18  Line 18 
18   */   */
19    
20  #include "regionchooser.h"  #include "regionchooser.h"
21    
22    #include <algorithm>
23    
24    #include <cairomm/context.h>
25    #include <gdkmm/general.h>
26  #include <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
27  #include <gtkmm/stock.h>  #include <gtkmm/stock.h>
28  #include <gtkmm/spinbutton.h>  #include <gtkmm/spinbutton.h>
29  #include <gtkmm/dialog.h>  #include <gtkmm/dialog.h>
 #include <libintl.h>  
 #include <math.h>  
30    
31  #define _(String) gettext(String)  #include "global.h"
32    #include "Settings.h"
33    
34    #define REGION_BLOCK_HEIGHT             30
35    #define KEYBOARD_HEIGHT                 40
36    
37  RegionChooser::RegionChooser()  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    
63    
64    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    
     black = Gdk::Color("black");  
     white = Gdk::Color("white");  
     red = Gdk::Color("#8070ff");  
     blue = Gdk::Color("#c098ff");  
     green = Gdk::Color("#a088ff");  
     grey1 = Gdk::Color("red");  
   
     colormap->alloc_color(black);  
     colormap->alloc_color(white);  
     colormap->alloc_color(red);  
     colormap->alloc_color(blue);  
     colormap->alloc_color(green);  
     colormap->alloc_color(grey1);  
75      instrument = 0;      instrument = 0;
76      region = 0;      region = 0;
77      resize.active = false;      resize.active = false;
78        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 86  RegionChooser::RegionChooser() Line 138  RegionChooser::RegionChooser()
138      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
139                 Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK);                 Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK);
140    
141      dimensionManager.articulation_changed_signal.connect(      dimensionManager.region_to_be_changed_signal.connect(
142          sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed)          region_to_be_changed_signal.make_slot()
143        );
144        dimensionManager.region_changed_signal.connect(
145            region_changed_signal.make_slot()
146        );
147        dimensionManager.region_changed_signal.connect(
148            sigc::hide(
149                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::on_realize()  void RegionChooser::invalidate_key(int key) {
166  {      const int h = KEYBOARD_HEIGHT;
167      // We need to call the base on_realize()      const int w = get_width() - 1;
168      Gtk::DrawingArea::on_realize();      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) {
176        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) {
182        key_pressed[key] = false;
183        invalidate_key(key);
184        m_VirtKeybOffVelocityLabel.set_text(ToString(velocity));
185    }
186    
187      // Now we can allocate any additional resources we need  
188      Glib::RefPtr<Gdk::Window> window = get_window();  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
189      gc = Gdk::GC::create(window);  bool RegionChooser::on_expose_event(GdkEventExpose* e) {
190      window->clear();      double clipx1 = e->area.x;
191        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        cr->save();
207        cr->set_line_width(1);
208    
209    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
210        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  bool RegionChooser::on_expose_event(GdkEventExpose* event)  void RegionChooser::draw_keyboard(const Cairo::RefPtr<Cairo::Context>& cr,
231  {                                    int clip_low, int clip_high) {
232      Glib::RefPtr<Gdk::Window> window = get_window();      const int h = KEYBOARD_HEIGHT;
233      window->clear();      const int w = get_width() - 1;
     const int h = 40;  
     const int w = 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);
255      window->draw_rectangle(white, true, 1, h1 + 1, w - 1, h - 2);  
256      for (int i = 0 ; i < 128 ; i++) {      int clipkey1 = std::max(0, x_to_key_right(clip_low - 1, w));
257          int note = (i + 3) % 12;      int clipkey2 = std::min(x_to_key_right(clip_high - 1, w) + 1, 128);
         int x = int(w * i / 128.0 + 0.5);  
258    
259          if (note == 1 || note == 4 || note == 6 || note == 9 || note == 11) {      for (int i = clipkey1 ; i < clipkey2 ; i++) {
260              int x2 = int(w * (i + 0.5) / 128.0 + 0.5);          int note = (i + 3) % 12;
261              window->draw_line(black, x2, h1 + bh, x2, h1 + h);          int x = key_to_x(i, w);
262    
263              int x3 = int(w * (i + 1) / 128.0 + 0.5);          if (note == 1 || note == 4 || note == 6 ||
264              window->draw_rectangle(black, true, x, h1 + 1, x3 - x + 1, bh);              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    
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 *nextRegion;  
         int x3 = -1;  
         for (gig::Region *r = instrument->GetFirstRegion() ;  
              r ;  
              r = nextRegion) {  
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              nextRegion = instrument->GetNextRegion();                                   int clip_low, int clip_high) {
291              if (!nextRegion || r->KeyRange.high + 1 != nextRegion->KeyRange.low) {      const int w = get_width() - 1;
292                  int x2 = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);  
293                  window->draw_line(black, x3, 0, x2, 0);      Gdk::Cairo::set_source_rgba(cr, black);
294                  window->draw_line(black, x3, h1 - 1, x2, h1 - 1);      gig::Region* next_region;
295                  window->draw_line(black, x2, 1, x2, h1 - 2);      int x3 = -1;
296                  window->draw_rectangle(white, true, x3 + 1, 1, x2 - x3 - 1, h1 - 2);      for (gig::Region* r = regions.first() ; r ; r = next_region) {
297                  x3 = -1;          next_region = regions.next();
298    
299            if (x3 < 0) {
300                x3 = key_to_x(r->KeyRange.low, w);
301                if (x3 >= clip_high) break;
302            }
303            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              i++;              x3 = -1;
321          }          }
322        }
323    
324          for (gig::Region *r = instrument->GetFirstRegion() ;      for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
325               r ;          int x = key_to_x(r->KeyRange.low, w);
              r = instrument->GetNextRegion()) {  
             int x = int(w * (r->KeyRange.low) / 128.0 + 0.5);  
             window->draw_line(black, x, 1, x, h1 - 2);  
         }  
326    
327          if (region) {          if (x < clip_low) continue;
328              int x1 = int(w * (region->KeyRange.low) / 128.0 + 0.5);          if (x >= clip_high) break;
             int x2 = int(w * (region->KeyRange.high + 1) / 128.0 + 0.5);  
             gc->set_foreground(red);  
             window->draw_rectangle(gc, true, x1 + 1, 1, x2 - x1 - 1, h1 - 2);  
         }  
     }  
     return true;  
 }  
329    
330            cr->move_to(x + 0.5, 1);
331            cr->line_to(x + 0.5, h1 - 1);
332            cr->stroke();
333        }
334    
335  void RegionChooser::on_size_request(GtkRequisition* requisition)      // 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      *requisition = GtkRequisition();      if (!regions.first()) {
338      requisition->height = 40 + 20;          Glib::RefPtr<Pango::Context> context = get_pango_context();
339      requisition->width = 500;          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            Pango::Rectangle rect = layout->get_logical_extents();
348            int text_width, text_height;
349            layout->get_pixel_size(text_width, text_height);
350            cr->move_to(0, (REGION_BLOCK_HEIGHT - text_height) / 2);
351    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
352            pango_cairo_show_layout(cr->cobj(), layout->gobj());
353    #else
354            layout->show_in_cairo_context(cr);
355    #endif
356        }
357  }  }
358    
359    bool RegionChooser::is_black_key(int key) {
360  // not used      const int note = (key + 3) % 12;
361  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)      return note == 1 || note == 4 || note == 6 || note == 9 || note == 11;
362  {  }
363      const int h = 40;  
364      const int w = width;  void RegionChooser::draw_digit(const Cairo::RefPtr<Cairo::Context>& cr,
365                                   int key) {
366        const int h = KEYBOARD_HEIGHT;
367        const int w = get_width() - 1;
368        Glib::RefPtr<Pango::Layout> layout =
369            Pango::Layout::create(get_pango_context());
370        char buf[30];
371        sprintf(buf, "<span size=\"8000\">%d</span>", key / 12 - 1);
372        layout->set_markup(buf);
373        Pango::Rectangle rectangle = layout->get_logical_extents();
374        double text_w = double(rectangle.get_width()) / Pango::SCALE;
375        double text_h = double(rectangle.get_height()) / Pango::SCALE;
376        double x = w * (key + 0.75) / 128.0;
377        Gdk::Cairo::set_source_rgba(cr, black);
378        cr->move_to(int(x - text_w / 2 + 1), int(h1 + h - text_h + 0.5));
379    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
380        pango_cairo_show_layout(cr->cobj(), layout->gobj());
381    #else
382        layout->show_in_cairo_context(cr);
383    #endif
384    }
385    
386    void RegionChooser::draw_key(const Cairo::RefPtr<Cairo::Context>& cr,
387                                 int key) {
388        const int h = KEYBOARD_HEIGHT;
389        const int w = get_width() - 1;
390      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
391    
392      Glib::RefPtr<Gdk::Window> window = get_window();      Gdk::Cairo::set_source_rgba(cr, activeKeyColor);
     gc->set_foreground(color);  
393    
394      for (int i = from ; i < to ; i++) {      int note = (key + 3) % 12;
395          int note = (i + 3) % 12;      int x = key_to_x(key, w) + 1;
396          int x = int(w * i / 128.0 + 0.5) + 1;      int x2 = key_to_x(key + 1.5, w);
397          int x2 = int(w * (i + 1.5) / 128.0 + 0.5);      int x3 = key_to_x(key + 1, w);
398          int x3 = int(w * (i + 1) / 128.0 + 0.5);      int x4 = key_to_x(key - 0.5, w);
399          int x4 = int(w * (i - 0.5) / 128 + 0.5) + 1;      int w1 = x3 - x;
400          int w1 = x3 - x;      switch (note) {
401          switch (note) {      case 0: case 5: case 10:
402          case 0: case 5: case 10:          cr->rectangle(x, h1 + 1, w1, bh);
403              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);          cr->fill();
404              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);
405              break;          cr->fill();
406          case 2: case 7:          break;
407              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);      case 2: case 7:
408              window->draw_rectangle(gc, true, x4, h1 + bh + 1, x3 - x4, h - bh - 2);          cr->rectangle(x, h1 + 1, w1, bh);
409              break;          cr->fill();
410          case 3: case 8:          cr->rectangle(x4 + 1, h1 + bh + 1, x3 - x4 - 1, h - bh - 2);
411              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh);          cr->fill();
412              window->draw_rectangle(gc, true, x, h1 + bh + 1, x2 - x, h - bh - 2);          break;
413              break;      case 3: case 8:
414          default:          cr->rectangle(x, h1 + 1, w1, bh);
415              window->draw_rectangle(gc, true, x, h1 + 1, w1, bh - 1);          cr->fill();
416              break;          cr->rectangle(x, h1 + bh + 1, x2 - x, h - bh - 2);
417          }          cr->fill();
418            break;
419        default:
420            cr->rectangle(x, h1 + 1, w1, bh - 1);
421            cr->fill();
422            break;
423      }      }
424        Gdk::Cairo::set_source_rgba(cr, black);
425  }  }
426    
427  void RegionChooser::set_instrument(gig::Instrument* instrument)  void RegionChooser::set_instrument(gig::Instrument* instrument)
428  {  {
429      this->instrument = instrument;      this->instrument = instrument;
430      region = instrument ? instrument->GetFirstRegion() : 0;      regions.update(instrument);
431        region = regions.first();
432      queue_draw();      queue_draw();
433      region_selected();      region_selected();
434        dimensionManager.set_region(region);
435  }  }
436    
437  bool RegionChooser::on_button_release_event(GdkEventButton* event)  bool RegionChooser::on_button_release_event(GdkEventButton* event)
438  {  {
439        const int k = x_to_key(event->x, get_width() - 1);
440    
441        // handle-note off on virtual keyboard
442        if (event->type == GDK_BUTTON_RELEASE) {
443            int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
444                           int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
445            if (velocity <= 0) velocity = 1;
446            switch (m_VirtKeybModeChoice.get_value()) {
447                case VIRT_KEYBOARD_MODE_CHORD:
448                    if (event->y >= REGION_BLOCK_HEIGHT)
449                        keyboard_key_released_signal.emit(k, velocity);
450                    break;
451                case VIRT_KEYBOARD_MODE_NORMAL:
452                default:
453                    if (currentActiveKey >= 0 && currentActiveKey <= 127) {
454                        keyboard_key_released_signal.emit(currentActiveKey, velocity);
455                        currentActiveKey = -1;
456                    }
457                    break;
458            }
459        }
460    
461      if (resize.active) {      if (resize.active) {
462    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
463          get_window()->pointer_ungrab(event->time);          get_window()->pointer_ungrab(event->time);
464    #else
465            Glib::wrap(event->device, true)->ungrab(event->time);
466    #endif
467          resize.active = false;          resize.active = false;
468    
         if (resize.mode == resize.moving_high_limit) {  
             if (resize.region->KeyRange.high != resize.pos - 1) {  
                 resize.region->KeyRange.high = resize.pos - 1;  
                 instrument_changed();  
             }  
         } else if (resize.mode == resize.moving_low_limit) {  
             if (resize.region->KeyRange.low != resize.pos) {  
                 resize.region->KeyRange.low = resize.pos;  
                 instrument_changed();  
             }  
         }  
   
469          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
470              get_window()->set_cursor();              get_window()->set_cursor();
471              cursor_is_resize = false;              cursor_is_resize = false;
472          }          }
473        } else if (move.active) {
474    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
475            get_window()->pointer_ungrab(event->time);
476    #else
477            Glib::wrap(event->device, true)->ungrab(event->time);
478    #endif
479            move.active = false;
480    
481            if (is_in_resize_zone(event->x, event->y)) {
482    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
483                get_window()->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
484    #else
485                get_window()->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
486    #endif
487                cursor_is_resize = true;
488            }
489      }      }
490      return true;      return true;
491  }  }
492    
493    void RegionChooser::update_after_resize()
494    {
495        if (resize.mode == resize.moving_high_limit) {
496            if (resize.region->KeyRange.high != resize.pos - 1) {
497                instrument_struct_to_be_changed_signal.emit(instrument);
498                resize.region->SetKeyRange(resize.region->KeyRange.low,
499                                           resize.pos - 1);
500                regions.update(instrument);
501                instrument_changed.emit();
502                instrument_struct_changed_signal.emit(instrument);
503            }
504        } else if (resize.mode == resize.moving_low_limit) {
505            if (resize.region->KeyRange.low != resize.pos) {
506                instrument_struct_to_be_changed_signal.emit(instrument);
507                resize.region->SetKeyRange(resize.pos,
508                                           resize.region->KeyRange.high);
509                regions.update(instrument);
510                instrument_changed.emit();
511                instrument_struct_changed_signal.emit(instrument);
512            }
513        }
514    }
515    
516    void RegionChooser::update_after_move(int pos)
517    {
518        instrument_struct_to_be_changed_signal.emit(instrument);
519        const int range = region->KeyRange.high - region->KeyRange.low;
520        const int diff  = pos - int(region->KeyRange.low);
521        region->SetKeyRange(pos, pos + range);
522        if (Settings::singleton()->moveRootNoteWithRegionMoved) {
523            for (int i = 0; i < 256; ++i) {
524                gig::DimensionRegion* dimrgn = region->pDimensionRegions[i];
525                if (!dimrgn || !dimrgn->pSample || !dimrgn->PitchTrack) continue;
526                dimrgn->UnityNote += diff;
527            }
528        }
529        regions.update(instrument);
530        instrument_changed.emit();
531        instrument_struct_changed_signal.emit(instrument);
532    }
533    
534  bool RegionChooser::on_button_press_event(GdkEventButton* event)  bool RegionChooser::on_button_press_event(GdkEventButton* event)
535  {  {
536      if (!instrument) return true;      if (!instrument) return true;
537    
538      int k = int(event->x / (width - 1) * 128.0);      const int w = get_width() - 1;
539        const int k = x_to_key(event->x, w);
540    
541        if (event->type == GDK_BUTTON_PRESS) {
542            if (event->y >= REGION_BLOCK_HEIGHT) {
543                int velocity = (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
544                               int(float(event->y - REGION_BLOCK_HEIGHT) / float(KEYBOARD_HEIGHT) * 128.0f) + 1;
545                currentActiveKey = k;
546                keyboard_key_hit_signal.emit(k, velocity);
547            }
548        }
549    
550        // left mouse button double click
551        if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
552            if (event->y < REGION_BLOCK_HEIGHT) {
553                // show dimension manager dialog for this region
554                manage_dimensions();
555            }
556        }
557    
558        if (event->y >= REGION_BLOCK_HEIGHT) return true;
559      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
560          gig::Region* r = get_region(k);          gig::Region* r = get_region(k);
561          if (r) {          if (r) {
562              region = r;              region = r;
563              queue_draw();              queue_draw();
564              region_selected();              region_selected();
565                dimensionManager.set_region(region);
566              popup_menu_inside_region->popup(event->button, event->time);              popup_menu_inside_region->popup(event->button, event->time);
567          } else {          } else {
568              new_region_pos = k;              new_region_pos = k;
# Line 271  bool RegionChooser::on_button_press_even Line 570  bool RegionChooser::on_button_press_even
570          }          }
571      } else {      } else {
572          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
573              Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
574              get_window()->pointer_grab(false,              get_window()->pointer_grab(false,
575                                         Gdk::BUTTON_RELEASE_MASK |                                         Gdk::BUTTON_RELEASE_MASK |
576                                         Gdk::POINTER_MOTION_MASK |                                         Gdk::POINTER_MOTION_MASK |
577                                         Gdk::POINTER_MOTION_HINT_MASK,                                         Gdk::POINTER_MOTION_HINT_MASK,
578                                         double_arrow, event->time);                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW),
579                                           event->time);
580    #else
581                Glib::wrap(event->device, true)->grab(get_window(),
582                                                      Gdk::OWNERSHIP_NONE,
583                                                      false,
584                                                      Gdk::BUTTON_RELEASE_MASK |
585                                                      Gdk::POINTER_MOTION_MASK |
586                                                      Gdk::POINTER_MOTION_HINT_MASK,
587                                                      Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW),
588                                                      event->time);
589    #endif
590              resize.active = true;              resize.active = true;
591          } else {          } else {
592              gig::Region* r = get_region(k);              gig::Region* r = get_region(k);
# Line 284  bool RegionChooser::on_button_press_even Line 594  bool RegionChooser::on_button_press_even
594                  region = r;                  region = r;
595                  queue_draw();                  queue_draw();
596                  region_selected();                  region_selected();
597                    dimensionManager.set_region(region);
598    
599    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
600                    get_window()->pointer_grab(false,
601                                               Gdk::BUTTON_RELEASE_MASK |
602                                               Gdk::POINTER_MOTION_MASK |
603                                               Gdk::POINTER_MOTION_HINT_MASK,
604                                               Gdk::Cursor(Gdk::FLEUR),
605                                               event->time);
606    #else
607                    Glib::wrap(event->device, true)->grab(get_window(),
608                                                          Gdk::OWNERSHIP_NONE,
609                                                          false,
610                                                          Gdk::BUTTON_RELEASE_MASK |
611                                                          Gdk::POINTER_MOTION_MASK |
612                                                          Gdk::POINTER_MOTION_HINT_MASK,
613                                                          Gdk::Cursor::create(Gdk::FLEUR),
614                                                          event->time);
615    #endif
616                    move.active = true;
617                    move.offset = event->x - key_to_x(region->KeyRange.low, w);
618              }              }
619          }          }
620      }      }
# Line 292  bool RegionChooser::on_button_press_even Line 623  bool RegionChooser::on_button_press_even
623    
624  gig::Region* RegionChooser::get_region(int key)  gig::Region* RegionChooser::get_region(int key)
625  {  {
626      for (gig::Region *r = instrument->GetFirstRegion() ; r ;      for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
          r = instrument->GetNextRegion()) {  
627          if (key < r->KeyRange.low) return 0;          if (key < r->KeyRange.low) return 0;
628          if (key <= r->KeyRange.high) return r;          if (key <= r->KeyRange.high) return r;
629      }      }
630      return 0;      return 0;
631  }  }
632    
633  bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)  void RegionChooser::set_region(gig::Region* region) {
634        this->region = region;
635        queue_draw();
636        region_selected();
637        dimensionManager.set_region(region);
638    }
639    
640    void RegionChooser::motion_resize_region(int x, int y)
641  {  {
642      const int w = width - 1;      const int w = get_width() - 1;
     Glib::RefPtr<Gdk::Window> window = get_window();  
     int x, y;  
     Gdk::ModifierType state = Gdk::ModifierType(0);  
     window->get_pointer(x, y, state);  
     if (resize.active) {  
         int k = int(double(x) / w * 128.0 + 0.5);  
643    
644          if (k < resize.min) k = resize.min;      int k = int(double(x) / w * 128.0 + 0.5);
         else if (k > resize.max) k = resize.max;  
645    
646          if (k != resize.pos) {      if (k < resize.min) k = resize.min;
647              if (resize.mode == resize.undecided) {      else if (k > resize.max) k = resize.max;
648                  if (k < resize.pos) {  
649                      // edit high limit of prev_region      if (k != resize.pos) {
650                      resize.max = resize.region->KeyRange.low;          if (resize.mode == resize.undecided) {
651                      resize.region = resize.prev_region;              if (k < resize.pos) {
652                      resize.mode = resize.moving_high_limit;                  // edit high limit of prev_region
653                  } else {                  resize.max = resize.region->KeyRange.low;
654                      // edit low limit of region                  resize.region = resize.prev_region;
655                      resize.min = resize.prev_region->KeyRange.high + 1;                  resize.mode = resize.moving_high_limit;
656                      resize.mode = resize.moving_low_limit;              } else {
657                  }                  // edit low limit of region
658                    resize.min = resize.prev_region->KeyRange.high + 1;
659                    resize.mode = resize.moving_low_limit;
660                }
661            }
662            resize.pos = k;
663    
664            int x1, x2;
665            if (resize.mode == resize.moving_high_limit) {
666                if (resize.region->KeyRange.high < resize.pos - 1) {
667                    x1 = resize.region->KeyRange.high;
668                    x2 = resize.pos - 1;
669                } else {
670                    x1 = resize.pos - 1;
671                    x2 = resize.region->KeyRange.high;
672              }              }
673              Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();          } else {
674              Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();              if (resize.region->KeyRange.low < resize.pos) {
675              if (region == resize.region) {                  x1 = resize.region->KeyRange.low;
676                  gc->set_foreground(red);                  x2 = resize.pos;
677                  white = gc;              } else {
678                    x1 = resize.pos;
679                    x2 = resize.region->KeyRange.low;
680              }              }
681              Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);          }
682              int prevx = int(w * resize.pos / 128.0 + 0.5);          x1 = key_to_x(x1, w);
683              x = int(w * k / 128.0 + 0.5);          x2 = key_to_x(x2 + 1, w) + 1;
684            Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
685              if (resize.mode == resize.moving_high_limit) {  
686                  if (k > resize.pos) {          update_after_resize();
687                      window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);  
688                      window->draw_line(black, prevx, 0, x, 0);          get_window()->invalidate_rect(rect, false);
689                      window->draw_line(black, prevx, h1 - 1, x, h1 - 1);      }
690    }
691    
692    void RegionChooser::motion_move_region(int x, int y)
693    {
694        const int w = get_width() - 1;
695    
696        int l = int(double(x - move.offset) / w * 128.0 + 0.5);
697    
698        if (l == region->KeyRange.low) return;
699        int new_l;
700        int regionsize = region->KeyRange.high - region->KeyRange.low;
701        int a = 0;
702        if (l > region->KeyRange.low) {
703            for (gig::Region* r = regions.first() ; ; r = regions.next()) {
704                if (r != region) {
705                    int b = r ? r->KeyRange.low : 128;
706    
707                    // gap: from a to b (not inclusive b)
708    
709                    if (region->KeyRange.high >= b) {
710                        // not found the current gap yet, just continue
711                  } else {                  } else {
712                      int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);  
713                      window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);                      if (a > l) {
714                            // this gap is too far to the right, break
715                            break;
716                        }
717    
718                        int newhigh = std::min(l + regionsize, b - 1);
719                        int newlo = newhigh - regionsize;
720    
721                        if (newlo >= a) {
722                            // yes it fits - it's a candidate
723                            new_l = newlo;
724                        }
725                  }                  }
726              } else {                  if (!r) break;
727                  if (k < resize.pos) {                  a = r->KeyRange.high + 1;
728                      window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);              }
729                      window->draw_line(black, x, 0, prevx, 0);          }
730                      window->draw_line(black, x, h1 - 1, prevx, h1 - 1);      } else {
731            for (gig::Region* r = regions.first() ; ; r = regions.next()) {
732                if (r != region) {
733                    int b = r ? r->KeyRange.low : 128;
734    
735                    // gap from a to b (not inclusive b)
736    
737                    if (l + regionsize >= b) {
738                        // not found the current gap yet, just continue
739                  } else {                  } else {
740                      int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);  
741                      window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);                      if (a > region->KeyRange.low) {
742                            // this gap is too far to the right, break
743                            break;
744                        }
745    
746                        int newlo = std::max(l, a);
747                        int newhigh = newlo + regionsize;
748    
749                        if (newhigh < b) {
750                            // yes it fits - break as the first one is the best
751                            new_l = newlo;
752                            break;
753                        }
754                  }                  }
755                    if (!r) break;
756                    a = r->KeyRange.high + 1;
757              }              }
             window->draw_line(black, x, 1, x, h1 - 2);  
             resize.pos = k;  
758          }          }
759        }
760        if (new_l == region->KeyRange.low) return;
761    
762        int x1 = key_to_x(std::min(int(region->KeyRange.low), new_l), w);
763        int x2 = key_to_x(std::max(int(region->KeyRange.high),
764                                   new_l + regionsize) + 1, w) + 1;
765    
766        Gdk::Rectangle rect(x1, 0, x2 - x1, h1);
767        update_after_move(new_l);
768    
769        get_window()->invalidate_rect(rect, false);
770    }
771    
772    
773    bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)
774    {
775        Glib::RefPtr<Gdk::Window> window = get_window();
776        int x, y;
777        Gdk::ModifierType state = Gdk::ModifierType(0);
778        window->get_pointer(x, y, state);
779    
780        // handle virtual MIDI keyboard
781        if (m_VirtKeybModeChoice.get_value() != VIRT_KEYBOARD_MODE_CHORD &&
782            currentActiveKey > 0 &&
783            event->y >= REGION_BLOCK_HEIGHT &&
784            event->y < REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT)
785        {
786            const int k = x_to_key(event->x, get_width() - 1);
787            if (k != currentActiveKey) {
788                int velocity =
789                    (event->y >= REGION_BLOCK_HEIGHT + KEYBOARD_HEIGHT - 1) ? 127 :
790                    int(float(event->y - REGION_BLOCK_HEIGHT) /
791                        float(KEYBOARD_HEIGHT) * 128.0f) + 1;
792                if (velocity <= 0) velocity = 1;
793                keyboard_key_released_signal.emit(currentActiveKey, velocity);
794                currentActiveKey = k;
795                keyboard_key_hit_signal.emit(k, velocity);
796            }
797        }
798    
799        if (resize.active) {
800            motion_resize_region(x, y);
801        } else if (move.active) {
802            motion_move_region(x, y);
803      } else {      } else {
804          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
805              if (!cursor_is_resize) {              if (!cursor_is_resize) {
806                  Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
807                  window->set_cursor(double_arrow);                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
808    #else
809                    window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
810    #endif
811                  cursor_is_resize = true;                  cursor_is_resize = true;
812              }              }
813          } else if (cursor_is_resize) {          } else if (cursor_is_resize) {
# Line 375  bool RegionChooser::on_motion_notify_eve Line 820  bool RegionChooser::on_motion_notify_eve
820  }  }
821    
822  bool RegionChooser::is_in_resize_zone(double x, double y) {  bool RegionChooser::is_in_resize_zone(double x, double y) {
823      const int w = width - 1;      const int w = get_width() - 1;
824    
825      if (instrument && y >= 0 && y <= h1) {      if (instrument && y >= 0 && y <= h1) {
826          gig::Region* prev_region = 0;          gig::Region* prev_region = 0;
827          gig::Region* next_region;          gig::Region* next_region;
828          for (gig::Region* r = instrument->GetFirstRegion() ; r ; r = next_region) {          for (gig::Region* r = regions.first(); r ; r = next_region) {
829              next_region = instrument->GetNextRegion();              next_region = regions.next();
830    
831              int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);              int lo = key_to_x(r->KeyRange.low, w);
832              if (x <= lo - 2) break;              if (x <= lo - 2) break;
833              if (x < lo + 2) {              if (x < lo + 2) {
834                  resize.region = r;                  resize.region = r;
# Line 397  bool RegionChooser::is_in_resize_zone(do Line 842  bool RegionChooser::is_in_resize_zone(do
842                      resize.mode = resize.undecided;                      resize.mode = resize.undecided;
843                      resize.min = prev_region->KeyRange.low + 1;                      resize.min = prev_region->KeyRange.low + 1;
844                      resize.prev_region = prev_region;                      resize.prev_region = prev_region;
845                      return true;                      return resize.min != resize.max;
846                  }                  }
847    
848                  // edit low limit                  // edit low limit
849                  resize.mode = resize.moving_low_limit;                  resize.mode = resize.moving_low_limit;
850                  resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;                  resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;
851                  return true;                  return resize.min != resize.max;
852              }              }
853              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {              if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
854                  int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);                  int hi = key_to_x(r->KeyRange.high + 1, w);
855                  if (x <= hi - 2) break;                  if (x <= hi - 2) break;
856                  if (x < hi + 2) {                  if (x < hi + 2) {
857                      // edit high limit                      // edit high limit
# Line 415  bool RegionChooser::is_in_resize_zone(do Line 860  bool RegionChooser::is_in_resize_zone(do
860                      resize.mode = resize.moving_high_limit;                      resize.mode = resize.moving_high_limit;
861                      resize.min = r->KeyRange.low + 1;                      resize.min = r->KeyRange.low + 1;
862                      resize.max = next_region ? next_region->KeyRange.low : 128;                      resize.max = next_region ? next_region->KeyRange.low : 128;
863                      return true;                      return resize.min != resize.max;
864                  }                  }
865              }              }
866              prev_region = r;              prev_region = r;
# Line 424  bool RegionChooser::is_in_resize_zone(do Line 869  bool RegionChooser::is_in_resize_zone(do
869      return false;      return false;
870  }  }
871    
872  sigc::signal<void> RegionChooser::signal_region_selected()  sigc::signal<void>& RegionChooser::signal_region_selected()
873  {  {
874      return region_selected;      return region_selected;
875  }  }
876    
877  sigc::signal<void> RegionChooser::signal_instrument_changed()  sigc::signal<void>& RegionChooser::signal_instrument_changed()
878  {  {
879      return instrument_changed;      return instrument_changed;
880  }  }
# Line 437  sigc::signal<void> RegionChooser::signal Line 882  sigc::signal<void> RegionChooser::signal
882  void RegionChooser::show_region_properties()  void RegionChooser::show_region_properties()
883  {  {
884      if (!region) return;      if (!region) return;
885      Gtk::Dialog dialog("Region Properties", true /*modal*/);      Gtk::Dialog dialog(_("Region Properties"), true /*modal*/);
886      // add "Keygroup" checkbox      // add "Keygroup" checkbox
887      Gtk::CheckButton checkBoxKeygroup("Member of a Keygroup (Exclusive Group)");      Gtk::CheckButton checkBoxKeygroup(_("Member of a Keygroup (Exclusive Group)"));
888      checkBoxKeygroup.set_active(region->KeyGroup);      checkBoxKeygroup.set_active(region->KeyGroup);
889      dialog.get_vbox()->pack_start(checkBoxKeygroup);      dialog.get_vbox()->pack_start(checkBoxKeygroup);
890      checkBoxKeygroup.show();      checkBoxKeygroup.show();
891      // add "Keygroup" spinbox      // add "Keygroup" spinbox
892      Gtk::Adjustment adjustment(1, 1, pow(2,32));  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
893        Gtk::Adjustment adjustment(1, 1, 999);
894      Gtk::SpinButton spinBox(adjustment);      Gtk::SpinButton spinBox(adjustment);
895    #else
896        Gtk::SpinButton spinBox(Gtk::Adjustment::create(1, 1, 999));
897    #endif
898      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);      if (region->KeyGroup) spinBox.set_value(region->KeyGroup);
899      dialog.get_vbox()->pack_start(spinBox);      dialog.get_vbox()->pack_start(spinBox);
900      spinBox.show();      spinBox.show();
# Line 461  void RegionChooser::show_region_properti Line 910  void RegionChooser::show_region_properti
910    
911  void RegionChooser::add_region()  void RegionChooser::add_region()
912  {  {
913      gig::Region* r;      instrument_struct_to_be_changed_signal.emit(instrument);
     for (r = instrument->GetFirstRegion() ; r ; r = instrument->GetNextRegion()) {  
         if (r->KeyRange.low > new_region_pos) break;  
     }  
914    
915      region = instrument->AddRegion();      region = instrument->AddRegion();
916      region->KeyRange.low = region->KeyRange.high = new_region_pos;      region->SetKeyRange(new_region_pos, new_region_pos);
917    
918        instrument_struct_changed_signal.emit(instrument);
919        regions.update(instrument);
920    
     instrument->MoveRegion(region, r);  
921      queue_draw();      queue_draw();
922      region_selected();      region_selected();
923        dimensionManager.set_region(region);
924      instrument_changed();      instrument_changed();
925  }  }
926    
927  void RegionChooser::delete_region()  void RegionChooser::delete_region()
928  {  {
929        instrument_struct_to_be_changed_signal.emit(instrument);
930      instrument->DeleteRegion(region);      instrument->DeleteRegion(region);
931        instrument_struct_changed_signal.emit(instrument);
932        regions.update(instrument);
933    
934      region = 0;      region = 0;
935      queue_draw();      queue_draw();
936      region_selected();      region_selected();
937        dimensionManager.set_region(region);
938      instrument_changed();      instrument_changed();
939  }  }
940    
# Line 495  void RegionChooser::on_dimension_manager Line 949  void RegionChooser::on_dimension_manager
949      region_selected();      region_selected();
950      instrument_changed();      instrument_changed();
951  }  }
952    
953    sigc::signal<void, gig::Instrument*>& RegionChooser::signal_instrument_struct_to_be_changed() {
954        return instrument_struct_to_be_changed_signal;
955    }
956    
957    sigc::signal<void, gig::Instrument*>& RegionChooser::signal_instrument_struct_changed() {
958        return instrument_struct_changed_signal;
959    }
960    
961    sigc::signal<void, gig::Region*>& RegionChooser::signal_region_to_be_changed() {
962        return region_to_be_changed_signal;
963    }
964    
965    sigc::signal<void, gig::Region*>& RegionChooser::signal_region_changed_signal() {
966        return region_changed_signal;
967    }
968    
969    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_hit() {
970        return keyboard_key_hit_signal;
971    }
972    
973    sigc::signal<void, int/*key*/, int/*velocity*/>& RegionChooser::signal_keyboard_key_released() {
974        return keyboard_key_released_signal;
975    }

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

  ViewVC Help
Powered by ViewVC