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

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

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

revision 1053 by persson, Sat Mar 3 12:20:01 2007 UTC revision 1111 by schoenebeck, Fri Mar 23 00:22:44 2007 UTC
# Line 19  Line 19 
19    
20  #include "regionchooser.h"  #include "regionchooser.h"
21  #include <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
22    #include <gtkmm/stock.h>
23    #include <libintl.h>
24    
25    #define _(String) gettext(String)
26    
27  RegionChooser::RegionChooser()  RegionChooser::RegionChooser()
28  {  {
# Line 39  RegionChooser::RegionChooser() Line 43  RegionChooser::RegionChooser()
43      colormap->alloc_color(grey1);      colormap->alloc_color(grey1);
44      instrument = 0;      instrument = 0;
45      region = 0;      region = 0;
46        resize.active = false;
47      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK);      cursor_is_resize = false;
48        h1 = 20;
49        width = 800;
50    
51        actionGroup = Gtk::ActionGroup::create();
52        actionGroup->add(Gtk::Action::create("Properties",
53                                             Gtk::Stock::PROPERTIES),
54                         sigc::mem_fun(*this,
55                                       &RegionChooser::show_region_properties));
56        actionGroup->add(Gtk::Action::create("Remove", Gtk::Stock::REMOVE),
57                         sigc::mem_fun(*this, &RegionChooser::delete_region));
58        actionGroup->add(Gtk::Action::create("Add", Gtk::Stock::ADD),
59                         sigc::mem_fun(*this, &RegionChooser::add_region));
60        actionGroup->add(Gtk::Action::create("Dimensions", _("Dimensions...")),
61                         sigc::mem_fun(*this, &RegionChooser::manage_dimensions));
62    
63        uiManager = Gtk::UIManager::create();
64        uiManager->insert_action_group(actionGroup);
65        Glib::ustring ui_info =
66            "<ui>"
67            "  <popup name='PopupMenuInsideRegion'>"
68            "    <menuitem action='Properties'/>"
69            "    <menuitem action='Dimensions'/>"
70            "    <menuitem action='Remove'/>"
71            "  </popup>"
72            "  <popup name='PopupMenuOutsideRegion'>"
73            "    <menuitem action='Add'/>"
74            "  </popup>"
75            "</ui>";
76        uiManager->add_ui_from_string(ui_info);
77    
78        popup_menu_inside_region = dynamic_cast<Gtk::Menu*>(
79            uiManager->get_widget("/PopupMenuInsideRegion"));
80        popup_menu_outside_region = dynamic_cast<Gtk::Menu*>(
81            uiManager->get_widget("/PopupMenuOutsideRegion"));
82    
83        add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
84                   Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK);
85    
86        dimensionManager.articulation_changed_signal.connect(
87            sigc::mem_fun(*this, &RegionChooser::on_dimension_manager_changed)
88        );
89  }  }
90    
91  RegionChooser::~RegionChooser()  RegionChooser::~RegionChooser()
# Line 62  bool RegionChooser::on_expose_event(GdkE Line 107  bool RegionChooser::on_expose_event(GdkE
107  {  {
108      Glib::RefPtr<Gdk::Window> window = get_window();      Glib::RefPtr<Gdk::Window> window = get_window();
109      window->clear();      window->clear();
     const int h1 = 20;  
110      const int h = 40;      const int h = 40;
111      const int w = 800 - 1;      const int w = width - 1;
112      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
113    
114      Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();      Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
# Line 105  bool RegionChooser::on_expose_event(GdkE Line 149  bool RegionChooser::on_expose_event(GdkE
149                  window->draw_rectangle(white, true, x3 + 1, 1, x2 - x3 - 1, h1 - 2);                  window->draw_rectangle(white, true, x3 + 1, 1, x2 - x3 - 1, h1 - 2);
150                  x3 = -1;                  x3 = -1;
151              }              }
 //          draw_region(r->KeyRange.low, r->KeyRange.high + 1, i % 3 == 0 ? blue : i % 3 == 1 ? red : green);  
152              i++;              i++;
153          }          }
154    
# Line 135  void RegionChooser::on_size_request(GtkR Line 178  void RegionChooser::on_size_request(GtkR
178  }  }
179    
180    
181    // not used
182  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)
183  {  {
     const int h1 = 20;  
184      const int h = 40;      const int h = 40;
185      const int w = 800;      const int w = width;
186      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
187    
188      Glib::RefPtr<Gdk::Window> window = get_window();      Glib::RefPtr<Gdk::Window> window = get_window();
# Line 175  void RegionChooser::draw_region(int from Line 218  void RegionChooser::draw_region(int from
218  void RegionChooser::set_instrument(gig::Instrument* instrument)  void RegionChooser::set_instrument(gig::Instrument* instrument)
219  {  {
220      this->instrument = instrument;      this->instrument = instrument;
221      region = instrument->GetFirstRegion();      region = instrument ? instrument->GetFirstRegion() : 0;
222      queue_draw();      queue_draw();
223      sel_changed_signal.emit();      sel_changed_signal.emit();
224  }  }
225    
226  void RegionChooser::set_region(gig::Region* region)  bool RegionChooser::on_button_release_event(GdkEventButton* event)
227  {  {
228      this->region = region;      if (resize.active) {
229      queue_draw();          get_window()->pointer_ungrab(event->time);
230            resize.active = false;
231    
232            if (resize.mode == resize.moving_high_limit) {
233                resize.region->KeyRange.high = resize.pos - 1;
234            } else if (resize.mode == resize.moving_low_limit) {
235                resize.region->KeyRange.low = resize.pos;
236            }
237    
238            if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
239                get_window()->set_cursor();
240                cursor_is_resize = false;
241            }
242        }
243        return true;
244  }  }
245    
246  bool RegionChooser::on_button_press_event(GdkEventButton* event)  bool RegionChooser::on_button_press_event(GdkEventButton* event)
247  {  {
248      const int w = 800 - 1;      if (!instrument) return true;
249    
250      if (instrument) {      int k = int(event->x / (width - 1) * 128.0);
251          int i = 0;  
252          for (gig::Region *r = instrument->GetFirstRegion() ;      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
253               r ;          gig::Region* r = get_region(k);
254               r = instrument->GetNextRegion()) {          if (r) {
255              int x = int(w * (r->KeyRange.low) / 128.0 + 0.5);              region = r;
256              int x2 = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);              queue_draw();
257              if (event->x >= x && event->x < x2) {              sel_changed_signal.emit();
258                popup_menu_inside_region->popup(event->button, event->time);
259            } else {
260                new_region_pos = k;
261                popup_menu_outside_region->popup(event->button, event->time);
262            }
263        } else {
264            if (is_in_resize_zone(event->x, event->y)) {
265                Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
266                get_window()->pointer_grab(false,
267                                           Gdk::BUTTON_RELEASE_MASK |
268                                           Gdk::POINTER_MOTION_MASK |
269                                           Gdk::POINTER_MOTION_HINT_MASK,
270                                           double_arrow, event->time);
271                resize.active = true;
272            } else {
273                gig::Region* r = get_region(k);
274                if (r) {
275                  region = r;                  region = r;
276                  break;                  queue_draw();
277                    sel_changed_signal.emit();
278              }              }
             i++;  
279          }          }
         queue_draw();  
         sel_changed_signal.emit();  
280      }      }
281        return true;
282    }
283    
284    gig::Region* RegionChooser::get_region(int key)
285    {
286        for (gig::Region *r = instrument->GetFirstRegion() ; r ;
287             r = instrument->GetNextRegion()) {
288            if (key < r->KeyRange.low) return 0;
289            if (key <= r->KeyRange.high) return r;
290        }
291        return 0;
292  }  }
293    
 // muspekarexperiment. Fel eventhantering - se example_drawingarea.cc  
 bool inside = false;  
294  bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)  bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)
295  {  {
296      if (event->x > 100 && event->x < 120) {      const int w = width - 1;
297          if (!inside) {      Glib::RefPtr<Gdk::Window> window = get_window();
298              Gdk::Cursor oj(Gdk::CROSSHAIR);      int x, y;
299              get_window()->set_cursor(oj);      Gdk::ModifierType state = Gdk::ModifierType(0);
300              inside = true;      window->get_pointer(x, y, state);
301          }      if (resize.active) {
302      } else if (inside) {          int k = int(double(x) / w * 128.0 + 0.5);
303          get_window()->set_cursor();  
304          inside = false;          if (k < resize.min) k = resize.min;
305            else if (k > resize.max) k = resize.max;
306    
307            if (k != resize.pos) {
308                if (resize.mode == resize.undecided) {
309                    if (k < resize.pos) {
310                        // edit high limit of prev_region
311                        resize.max = resize.region->KeyRange.low;
312                        resize.region = resize.prev_region;
313                        resize.mode = resize.moving_high_limit;
314                    } else {
315                        // edit low limit of region
316                        resize.min = resize.prev_region->KeyRange.high + 1;
317                        resize.mode = resize.moving_low_limit;
318                    }
319                }
320                Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
321                Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();
322                if (region == resize.region) {
323                    gc->set_foreground(red);
324                    white = gc;
325                }
326                Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);
327                int prevx = int(w * resize.pos / 128.0 + 0.5);
328                x = int(w * k / 128.0 + 0.5);
329    
330                if (resize.mode == resize.moving_high_limit) {
331                    if (k > resize.pos) {
332                        window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);
333                        window->draw_line(black, prevx, 0, x, 0);
334                        window->draw_line(black, prevx, h1 - 1, x, h1 - 1);
335                    } else {
336                        int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);
337                        window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);
338                    }
339                } else {
340                    if (k < resize.pos) {
341                        window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);
342                        window->draw_line(black, x, 0, prevx, 0);
343                        window->draw_line(black, x, h1 - 1, prevx, h1 - 1);
344                    } else {
345                        int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);
346                        window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);
347                    }
348                }
349                window->draw_line(black, x, 1, x, h1 - 2);
350                resize.pos = k;
351            }
352        } else {
353            if (is_in_resize_zone(x, y)) {
354                if (!cursor_is_resize) {
355                    Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
356                    window->set_cursor(double_arrow);
357                    cursor_is_resize = true;
358                }
359            } else if (cursor_is_resize) {
360                window->set_cursor();
361                cursor_is_resize = false;
362            }
363        }
364    
365        return true;
366    }
367    
368    bool RegionChooser::is_in_resize_zone(double x, double y) {
369        const int w = width - 1;
370    
371        if (instrument && y >= 0 && y <= h1) {
372            gig::Region* prev_region = 0;
373            gig::Region* next_region;
374            for (gig::Region* r = instrument->GetFirstRegion() ; r ; r = next_region) {
375                next_region = instrument->GetNextRegion();
376    
377                int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);
378                if (x <= lo - 2) break;
379                if (x < lo + 2) {
380                    resize.region = r;
381                    resize.pos = r->KeyRange.low;
382                    resize.max = r->KeyRange.high;
383    
384                    if (prev_region && prev_region->KeyRange.high + 1 == r->KeyRange.low) {
385                        // we don't know yet if it's the high limit of
386                        // prev_region or the low limit of r that's going
387                        // to be edited
388                        resize.mode = resize.undecided;
389                        resize.min = prev_region->KeyRange.low + 1;
390                        resize.prev_region = prev_region;
391                        return true;
392                    }
393    
394                    // edit low limit
395                    resize.mode = resize.moving_low_limit;
396                    resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;
397                    return true;
398                }
399                if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
400                    int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);
401                    if (x <= hi - 2) break;
402                    if (x < hi + 2) {
403                        // edit high limit
404                        resize.region = r;
405                        resize.pos = r->KeyRange.high + 1;
406                        resize.mode = resize.moving_high_limit;
407                        resize.min = r->KeyRange.low + 1;
408                        resize.max = next_region ? next_region->KeyRange.low : 128;
409                        return true;
410                    }
411                }
412                prev_region = r;
413            }
414      }      }
415        return false;
416  }  }
417    
418  sigc::signal<void> RegionChooser::signal_sel_changed()  sigc::signal<void> RegionChooser::signal_sel_changed()
419  {  {
420      return sel_changed_signal;      return sel_changed_signal;
421  }  }
422    
423    void RegionChooser::show_region_properties()
424    {
425    }
426    
427    void RegionChooser::add_region()
428    {
429        gig::Region* r;
430        for (r = instrument->GetFirstRegion() ; r ; r = instrument->GetNextRegion()) {
431            if (r->KeyRange.low > new_region_pos) break;
432        }
433    
434        region = instrument->AddRegion();
435        region->KeyRange.low = region->KeyRange.high = new_region_pos;
436    
437        instrument->MoveRegion(region, r);
438        queue_draw();
439        sel_changed_signal.emit();
440    }
441    
442    void RegionChooser::delete_region()
443    {
444        instrument->DeleteRegion(region);
445        region = 0;
446        queue_draw();
447        sel_changed_signal.emit();
448    }
449    
450    void RegionChooser::manage_dimensions()
451    {
452        gig::Region* region = get_region();
453        if (!region) return;
454        dimensionManager.show(region);
455    }
456    
457    void RegionChooser::on_dimension_manager_changed() {
458        sel_changed_signal.emit();
459    }

Legend:
Removed from v.1053  
changed lines
  Added in v.1111

  ViewVC Help
Powered by ViewVC