/[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 1104 by persson, Sun Mar 18 17:15:00 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    
24  RegionChooser::RegionChooser()  RegionChooser::RegionChooser()
25  {  {
# Line 39  RegionChooser::RegionChooser() Line 40  RegionChooser::RegionChooser()
40      colormap->alloc_color(grey1);      colormap->alloc_color(grey1);
41      instrument = 0;      instrument = 0;
42      region = 0;      region = 0;
43        resize.active = false;
44        cursor_is_resize = false;
45        h1 = 20;
46        width = 800;
47    
48        actionGroup = Gtk::ActionGroup::create();
49        actionGroup->add(Gtk::Action::create("Properties",
50                                             Gtk::Stock::PROPERTIES),
51                         sigc::mem_fun(*this,
52                                       &RegionChooser::show_region_properties));
53        actionGroup->add(Gtk::Action::create("Remove", Gtk::Stock::REMOVE),
54                         sigc::mem_fun(*this, &RegionChooser::delete_region));
55        actionGroup->add(Gtk::Action::create("Add", Gtk::Stock::ADD),
56                         sigc::mem_fun(*this, &RegionChooser::add_region));
57    
58        uiManager = Gtk::UIManager::create();
59        uiManager->insert_action_group(actionGroup);
60        Glib::ustring ui_info =
61            "<ui>"
62            "  <popup name='PopupMenuInsideRegion'>"
63            "    <menuitem action='Properties'/>"
64            "    <menuitem action='Remove'/>"
65            "  </popup>"
66            "  <popup name='PopupMenuOutsideRegion'>"
67            "    <menuitem action='Add'/>"
68            "  </popup>"
69            "</ui>";
70        uiManager->add_ui_from_string(ui_info);
71    
72        popup_menu_inside_region = dynamic_cast<Gtk::Menu*>(
73            uiManager->get_widget("/PopupMenuInsideRegion"));
74        popup_menu_outside_region = dynamic_cast<Gtk::Menu*>(
75            uiManager->get_widget("/PopupMenuOutsideRegion"));
76    
77      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK);      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
78                   Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK);
79  }  }
80    
81  RegionChooser::~RegionChooser()  RegionChooser::~RegionChooser()
# Line 62  bool RegionChooser::on_expose_event(GdkE Line 97  bool RegionChooser::on_expose_event(GdkE
97  {  {
98      Glib::RefPtr<Gdk::Window> window = get_window();      Glib::RefPtr<Gdk::Window> window = get_window();
99      window->clear();      window->clear();
     const int h1 = 20;  
100      const int h = 40;      const int h = 40;
101      const int w = 800 - 1;      const int w = width - 1;
102      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
103    
104      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 139  bool RegionChooser::on_expose_event(GdkE
139                  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);
140                  x3 = -1;                  x3 = -1;
141              }              }
 //          draw_region(r->KeyRange.low, r->KeyRange.high + 1, i % 3 == 0 ? blue : i % 3 == 1 ? red : green);  
142              i++;              i++;
143          }          }
144    
# Line 135  void RegionChooser::on_size_request(GtkR Line 168  void RegionChooser::on_size_request(GtkR
168  }  }
169    
170    
171    // not used
172  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)  void RegionChooser::draw_region(int from, int to, const Gdk::Color& color)
173  {  {
     const int h1 = 20;  
174      const int h = 40;      const int h = 40;
175      const int w = 800;      const int w = width;
176      const int bh = int(h * 0.55);      const int bh = int(h * 0.55);
177    
178      Glib::RefPtr<Gdk::Window> window = get_window();      Glib::RefPtr<Gdk::Window> window = get_window();
# Line 175  void RegionChooser::draw_region(int from Line 208  void RegionChooser::draw_region(int from
208  void RegionChooser::set_instrument(gig::Instrument* instrument)  void RegionChooser::set_instrument(gig::Instrument* instrument)
209  {  {
210      this->instrument = instrument;      this->instrument = instrument;
211      region = instrument->GetFirstRegion();      region = instrument ? instrument->GetFirstRegion() : 0;
212      queue_draw();      queue_draw();
213      sel_changed_signal.emit();      sel_changed_signal.emit();
214  }  }
215    
216  void RegionChooser::set_region(gig::Region* region)  bool RegionChooser::on_button_release_event(GdkEventButton* event)
217  {  {
218      this->region = region;      if (resize.active) {
219      queue_draw();          get_window()->pointer_ungrab(event->time);
220            resize.active = false;
221    
222            if (resize.mode == resize.moving_high_limit) {
223                resize.region->KeyRange.high = resize.pos - 1;
224            } else if (resize.mode == resize.moving_low_limit) {
225                resize.region->KeyRange.low = resize.pos;
226            }
227    
228            if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
229                get_window()->set_cursor();
230                cursor_is_resize = false;
231            }
232        }
233        return true;
234  }  }
235    
236  bool RegionChooser::on_button_press_event(GdkEventButton* event)  bool RegionChooser::on_button_press_event(GdkEventButton* event)
237  {  {
238      const int w = 800 - 1;      if (!instrument) return true;
239    
240      if (instrument) {      int k = int(event->x / (width - 1) * 128.0);
241          int i = 0;  
242          for (gig::Region *r = instrument->GetFirstRegion() ;      if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
243               r ;          gig::Region* r = get_region(k);
244               r = instrument->GetNextRegion()) {          if (r) {
245              int x = int(w * (r->KeyRange.low) / 128.0 + 0.5);              region = r;
246              int x2 = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);              queue_draw();
247              if (event->x >= x && event->x < x2) {              sel_changed_signal.emit();
248                popup_menu_inside_region->popup(event->button, event->time);
249            } else {
250                new_region_pos = k;
251                popup_menu_outside_region->popup(event->button, event->time);
252            }
253        } else {
254            if (is_in_resize_zone(event->x, event->y)) {
255                Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
256                get_window()->pointer_grab(false,
257                                           Gdk::BUTTON_RELEASE_MASK |
258                                           Gdk::POINTER_MOTION_MASK |
259                                           Gdk::POINTER_MOTION_HINT_MASK,
260                                           double_arrow, event->time);
261                resize.active = true;
262            } else {
263                gig::Region* r = get_region(k);
264                if (r) {
265                  region = r;                  region = r;
266                  break;                  queue_draw();
267                    sel_changed_signal.emit();
268              }              }
             i++;  
269          }          }
         queue_draw();  
         sel_changed_signal.emit();  
270      }      }
271        return true;
272    }
273    
274    gig::Region* RegionChooser::get_region(int key)
275    {
276        for (gig::Region *r = instrument->GetFirstRegion() ; r ;
277             r = instrument->GetNextRegion()) {
278            if (key < r->KeyRange.low) return 0;
279            if (key <= r->KeyRange.high) return r;
280        }
281        return 0;
282  }  }
283    
 // muspekarexperiment. Fel eventhantering - se example_drawingarea.cc  
 bool inside = false;  
284  bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)  bool RegionChooser::on_motion_notify_event(GdkEventMotion* event)
285  {  {
286      if (event->x > 100 && event->x < 120) {      const int w = width - 1;
287          if (!inside) {      Glib::RefPtr<Gdk::Window> window = get_window();
288              Gdk::Cursor oj(Gdk::CROSSHAIR);      int x, y;
289              get_window()->set_cursor(oj);      Gdk::ModifierType state = Gdk::ModifierType(0);
290              inside = true;      window->get_pointer(x, y, state);
291          }      if (resize.active) {
292      } else if (inside) {          int k = int(double(x) / w * 128.0 + 0.5);
293          get_window()->set_cursor();  
294          inside = false;          if (k < resize.min) k = resize.min;
295            else if (k > resize.max) k = resize.max;
296    
297            if (k != resize.pos) {
298                if (resize.mode == resize.undecided) {
299                    if (k < resize.pos) {
300                        // edit high limit of prev_region
301                        resize.max = resize.region->KeyRange.low;
302                        resize.region = resize.prev_region;
303                        resize.mode = resize.moving_high_limit;
304                    } else {
305                        // edit low limit of region
306                        resize.min = resize.prev_region->KeyRange.high + 1;
307                        resize.mode = resize.moving_low_limit;
308                    }
309                }
310                Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
311                Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();
312                if (region == resize.region) {
313                    gc->set_foreground(red);
314                    white = gc;
315                }
316                Glib::RefPtr<const Gdk::GC> bg = get_style()->get_bg_gc(Gtk::STATE_NORMAL);
317                int prevx = int(w * resize.pos / 128.0 + 0.5);
318                x = int(w * k / 128.0 + 0.5);
319    
320                if (resize.mode == resize.moving_high_limit) {
321                    if (k > resize.pos) {
322                        window->draw_rectangle(white, true, prevx, 1, x - prevx, h1 - 2);
323                        window->draw_line(black, prevx, 0, x, 0);
324                        window->draw_line(black, prevx, h1 - 1, x, h1 - 1);
325                    } else {
326                        int xx = ((resize.pos == resize.max && resize.max != 128) ? 1 : 0);
327                        window->draw_rectangle(bg, true, x + 1, 0, prevx - x - xx, h1);
328                    }
329                } else {
330                    if (k < resize.pos) {
331                        window->draw_rectangle(white, true, x + 1, 1, prevx - x, h1 - 2);
332                        window->draw_line(black, x, 0, prevx, 0);
333                        window->draw_line(black, x, h1 - 1, prevx, h1 - 1);
334                    } else {
335                        int xx = ((resize.pos == resize.min && resize.min != 0) ? 1 : 0);
336                        window->draw_rectangle(bg, true, prevx + xx, 0, x - prevx - xx, h1);
337                    }
338                }
339                window->draw_line(black, x, 1, x, h1 - 2);
340                resize.pos = k;
341            }
342        } else {
343            if (is_in_resize_zone(x, y)) {
344                if (!cursor_is_resize) {
345                    Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
346                    window->set_cursor(double_arrow);
347                    cursor_is_resize = true;
348                }
349            } else if (cursor_is_resize) {
350                window->set_cursor();
351                cursor_is_resize = false;
352            }
353        }
354    
355        return true;
356    }
357    
358    bool RegionChooser::is_in_resize_zone(double x, double y) {
359        const int w = width - 1;
360    
361        if (instrument && y >= 0 && y <= h1) {
362            gig::Region* prev_region = 0;
363            gig::Region* next_region;
364            for (gig::Region* r = instrument->GetFirstRegion() ; r ; r = next_region) {
365                next_region = instrument->GetNextRegion();
366    
367                int lo = int(w * (r->KeyRange.low) / 128.0 + 0.5);
368                if (x <= lo - 2) break;
369                if (x < lo + 2) {
370                    resize.region = r;
371                    resize.pos = r->KeyRange.low;
372                    resize.max = r->KeyRange.high;
373    
374                    if (prev_region && prev_region->KeyRange.high + 1 == r->KeyRange.low) {
375                        // we don't know yet if it's the high limit of
376                        // prev_region or the low limit of r that's going
377                        // to be edited
378                        resize.mode = resize.undecided;
379                        resize.min = prev_region->KeyRange.low + 1;
380                        resize.prev_region = prev_region;
381                        return true;
382                    }
383    
384                    // edit low limit
385                    resize.mode = resize.moving_low_limit;
386                    resize.min = prev_region ? prev_region->KeyRange.high + 1 : 0;
387                    return true;
388                }
389                if (!next_region || r->KeyRange.high + 1 != next_region->KeyRange.low) {
390                    int hi = int(w * (r->KeyRange.high + 1) / 128.0 + 0.5);
391                    if (x <= hi - 2) break;
392                    if (x < hi + 2) {
393                        // edit high limit
394                        resize.region = r;
395                        resize.pos = r->KeyRange.high + 1;
396                        resize.mode = resize.moving_high_limit;
397                        resize.min = r->KeyRange.low + 1;
398                        resize.max = next_region ? next_region->KeyRange.low : 128;
399                        return true;
400                    }
401                }
402                prev_region = r;
403            }
404      }      }
405        return false;
406  }  }
407    
408  sigc::signal<void> RegionChooser::signal_sel_changed()  sigc::signal<void> RegionChooser::signal_sel_changed()
409  {  {
410      return sel_changed_signal;      return sel_changed_signal;
411  }  }
412    
413    void RegionChooser::show_region_properties()
414    {
415    }
416    
417    void RegionChooser::add_region()
418    {
419        gig::Region* r;
420        for (r = instrument->GetFirstRegion() ; r ; r = instrument->GetNextRegion()) {
421            if (r->KeyRange.low > new_region_pos) break;
422        }
423    
424        region = instrument->AddRegion();
425        region->KeyRange.low = region->KeyRange.high = new_region_pos;
426    
427        instrument->MoveRegion(region, r);
428        queue_draw();
429        sel_changed_signal.emit();
430    }
431    
432    void RegionChooser::delete_region()
433    {
434        instrument->DeleteRegion(region);
435        region = 0;
436        queue_draw();
437        sel_changed_signal.emit();
438    }

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

  ViewVC Help
Powered by ViewVC