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

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

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

revision 1420 by persson, Sun Oct 14 15:39:32 2007 UTC revision 2462 by schoenebeck, Wed Sep 4 20:23:05 2013 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 "dimregionchooser.h"  #include "dimregionchooser.h"
21    #include <cairomm/context.h>
22  #include <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
23    #include <gdkmm/general.h>
24    
25  DimRegionChooser::DimRegionChooser()  #include "global.h"
26    
27    DimRegionChooser::DimRegionChooser() :
28        red("#8070ff"),
29        black("black"),
30        white("white")
31  {  {
     // get_window() would return 0 because the Gdk::Window has not yet been realized  
     // So we can only allocate the colors here - the rest will happen in on_realize().  
     Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();  
   
     black = Gdk::Color("black");  
     white = Gdk::Color("white");  
     red = Gdk::Color("#8070ff");  
     blue = Gdk::Color("blue");  
     green = Gdk::Color("green");  
   
     colormap->alloc_color(black);  
     colormap->alloc_color(white);  
     colormap->alloc_color(red);  
     colormap->alloc_color(blue);  
     colormap->alloc_color(green);  
32      instrument = 0;      instrument = 0;
33      region = 0;      region = 0;
34      dimregno = -1;      dimregno = -1;
# Line 44  DimRegionChooser::DimRegionChooser() Line 36  DimRegionChooser::DimRegionChooser()
36      resize.active = false;      resize.active = false;
37      cursor_is_resize = false;      cursor_is_resize = false;
38      h = 20;      h = 20;
39      w = 800;      set_can_focus();
     set_flags(Gtk::CAN_FOCUS);  
40      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |
41                 Gdk::POINTER_MOTION_HINT_MASK);                 Gdk::POINTER_MOTION_HINT_MASK);
42    
43      for (int i = 0 ; i < 256 ; i++) dimvalue[i] = 0;      for (int i = 0 ; i < 256 ; i++) dimvalue[i] = 0;
44        labels_changed = true;
45  }  }
46    
47  DimRegionChooser::~DimRegionChooser()  DimRegionChooser::~DimRegionChooser()
48  {  {
49  }  }
50    
51  void DimRegionChooser::on_realize()  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
52    bool DimRegionChooser::on_expose_event(GdkEventExpose* e)
53  {  {
54      // We need to call the base on_realize()      double clipx1 = e->area.x;
55      Gtk::DrawingArea::on_realize();      double clipx2 = e->area.x + e->area.width;
56        double clipy1 = e->area.y;
57      // Now we can allocate any additional resources we need      double clipy2 = e->area.y + e->area.height;
58      Glib::RefPtr<Gdk::Window> window = get_window();  
59      gc = Gdk::GC::create(window);      const Cairo::RefPtr<Cairo::Context>& cr =
60            get_window()->create_cairo_context();
61    #if 0
62  }  }
63    #endif
64  bool DimRegionChooser::on_expose_event(GdkEventExpose* event)  #else
65    bool DimRegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
66  {  {
67        double clipx1, clipx2, clipy1, clipy2;
68        cr->get_clip_extents(clipx1, clipy1, clipx2, clipy2);
69    #endif
70    
71      if (!region) return true;      if (!region) return true;
72    
73      // This is where we draw on the window      // This is where we draw on the window
74      Glib::RefPtr<Gdk::Window> window = get_window();      int w = get_width();
75      Glib::RefPtr<Pango::Context> context = get_pango_context();      Glib::RefPtr<Pango::Context> context = get_pango_context();
76    
77      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
78        cr->set_line_width(1);
79    
     window->clear();  
   
     // draw labels on the left (reflecting the dimension type)  
80      int y = 0;      int y = 0;
81      double maxwidth = 0;      if (labels_changed || label_width - 10 > clipx1) {
82      for (int i = 0 ; i < region->Dimensions ; i++) {          // draw labels on the left (reflecting the dimension type)
83          int nbZones = region->pDimensionDefinitions[i].zones;          double maxwidth = 0;
84          if (nbZones) {          for (int i = 0 ; i < region->Dimensions ; i++) {
85              const char* dstr;              int nbZones = region->pDimensionDefinitions[i].zones;
86              char dstrbuf[10];              if (nbZones) {
87              switch (region->pDimensionDefinitions[i].dimension) {                  const char* dstr;
88              case gig::dimension_none: dstr="none"; break;                  char dstrbuf[10];
89              case gig::dimension_samplechannel: dstr="samplechannel"; break;                  switch (region->pDimensionDefinitions[i].dimension) {
90              case gig::dimension_layer: dstr="layer"; break;                  case gig::dimension_none: dstr=_("none"); break;
91              case gig::dimension_velocity: dstr="velocity"; break;                  case gig::dimension_samplechannel: dstr=_("samplechannel");
92              case gig::dimension_channelaftertouch: dstr="channelaftertouch"; break;                      break;
93              case gig::dimension_releasetrigger: dstr="releasetrigger"; break;                  case gig::dimension_layer: dstr=_("layer"); break;
94              case gig::dimension_keyboard: dstr="keyboard"; break;                  case gig::dimension_velocity: dstr=_("velocity"); break;
95              case gig::dimension_roundrobin: dstr="roundrobin"; break;                  case gig::dimension_channelaftertouch:
96              case gig::dimension_random: dstr="random"; break;                      dstr=_("channelaftertouch"); break;
97              case gig::dimension_smartmidi: dstr="smartmidi"; break;                  case gig::dimension_releasetrigger:
98              case gig::dimension_roundrobinkeyboard: dstr="roundrobinkeyboard"; break;                      dstr=_("releasetrigger"); break;
99              case gig::dimension_modwheel: dstr="modwheel"; break;                  case gig::dimension_keyboard: dstr=_("keyswitching"); break;
100              case gig::dimension_breath: dstr="breath"; break;                  case gig::dimension_roundrobin: dstr=_("roundrobin"); break;
101              case gig::dimension_foot: dstr="foot"; break;                  case gig::dimension_random: dstr=_("random"); break;
102              case gig::dimension_portamentotime: dstr="portamentotime"; break;                  case gig::dimension_smartmidi: dstr=_("smartmidi"); break;
103              case gig::dimension_effect1: dstr="effect1"; break;                  case gig::dimension_roundrobinkeyboard:
104              case gig::dimension_effect2: dstr="effect2"; break;                      dstr=_("roundrobinkeyboard"); break;
105              case gig::dimension_genpurpose1: dstr="genpurpose1"; break;                  case gig::dimension_modwheel: dstr=_("modwheel"); break;
106              case gig::dimension_genpurpose2: dstr="genpurpose2"; break;                  case gig::dimension_breath: dstr=_("breath"); break;
107              case gig::dimension_genpurpose3: dstr="genpurpose3"; break;                  case gig::dimension_foot: dstr=_("foot"); break;
108              case gig::dimension_genpurpose4: dstr="genpurpose4"; break;                  case gig::dimension_portamentotime:
109              case gig::dimension_sustainpedal: dstr="sustainpedal"; break;                      dstr=_("portamentotime"); break;
110              case gig::dimension_portamento: dstr="portamento"; break;                  case gig::dimension_effect1: dstr=_("effect1"); break;
111              case gig::dimension_sostenutopedal: dstr="sostenutopedal"; break;                  case gig::dimension_effect2: dstr=_("effect2"); break;
112              case gig::dimension_softpedal: dstr="softpedal"; break;                  case gig::dimension_genpurpose1: dstr=_("genpurpose1"); break;
113              case gig::dimension_genpurpose5: dstr="genpurpose5"; break;                  case gig::dimension_genpurpose2: dstr=_("genpurpose2"); break;
114              case gig::dimension_genpurpose6: dstr="genpurpose6"; break;                  case gig::dimension_genpurpose3: dstr=_("genpurpose3"); break;
115              case gig::dimension_genpurpose7: dstr="genpurpose7"; break;                  case gig::dimension_genpurpose4: dstr=_("genpurpose4"); break;
116              case gig::dimension_genpurpose8: dstr="genpurpose8"; break;                  case gig::dimension_sustainpedal:
117              case gig::dimension_effect1depth: dstr="effect1depth"; break;                      dstr=_("sustainpedal"); break;
118              case gig::dimension_effect2depth: dstr="effect2depth"; break;                  case gig::dimension_portamento: dstr=_("portamento"); break;
119              case gig::dimension_effect3depth: dstr="effect3depth"; break;                  case gig::dimension_sostenutopedal:
120              case gig::dimension_effect4depth: dstr="effect4depth"; break;                      dstr=_("sostenutopedal"); break;
121              case gig::dimension_effect5depth: dstr="effect5depth"; break;                  case gig::dimension_softpedal: dstr=_("softpedal"); break;
122              default:                  case gig::dimension_genpurpose5: dstr=_("genpurpose5"); break;
123                  sprintf(dstrbuf, "%d",                  case gig::dimension_genpurpose6: dstr=_("genpurpose6"); break;
124                          region->pDimensionDefinitions[i].dimension);                  case gig::dimension_genpurpose7: dstr=_("genpurpose7"); break;
125                  dstr = dstrbuf;                  case gig::dimension_genpurpose8: dstr=_("genpurpose8"); break;
126                  break;                  case gig::dimension_effect1depth:
127              }                      dstr=_("effect1depth"); break;
128              layout->set_text(dstr);                  case gig::dimension_effect2depth:
129                        dstr=_("effect2depth"); break;
130              Pango::Rectangle rectangle = layout->get_logical_extents();                  case gig::dimension_effect3depth:
131              double text_w = double(rectangle.get_width()) / Pango::SCALE;                      dstr=_("effect3depth"); break;
132              if (text_w > maxwidth) maxwidth = text_w;                  case gig::dimension_effect4depth:
133              double text_h = double(rectangle.get_height()) / Pango::SCALE;                      dstr=_("effect4depth"); break;
134              Glib::RefPtr<const Gdk::GC> fg = get_style()->get_fg_gc(get_state());                  case gig::dimension_effect5depth:
135              window->draw_layout(fg, 4, int(y + (h - text_h) / 2 + 0.5), layout);                      dstr=_("effect5depth"); break;
136                    default:
137                        sprintf(dstrbuf, "%d",
138                                region->pDimensionDefinitions[i].dimension);
139                        dstr = dstrbuf;
140                        break;
141                    }
142                    layout->set_text(dstr);
143    
144                    Pango::Rectangle rectangle = layout->get_logical_extents();
145                    double text_w = double(rectangle.get_width()) / Pango::SCALE;
146                    if (text_w > maxwidth) maxwidth = text_w;
147    
148                    if (y + h > clipy1 && y < clipy2 && text_w >= clipx1) {
149                        double text_h = double(rectangle.get_height()) /
150                            Pango::SCALE;
151    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
152                        const Gdk::Color fg = get_style()->get_fg(get_state());
153    #else
154                        const Gdk::RGBA fg =
155                            get_style_context()->get_color(get_state_flags());
156    #endif
157                        Gdk::Cairo::set_source_rgba(cr, fg);
158                        cr->move_to(4, int(y + (h - text_h) / 2 + 0.5));
159    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
160                        pango_cairo_show_layout(cr->cobj(), layout->gobj());
161    #else
162                        layout->show_in_cairo_context(cr);
163    #endif
164                    }
165                }
166                y += h;
167          }          }
168          y += h;          label_width = int(maxwidth + 10);
169            labels_changed = false;
170      }      }
171        if (label_width >= clipx2) return true;
172    
173      // draw dimensions' zones areas      // draw dimensions' zones areas
174      y = 0;      y = 0;
175      int bitpos = 0;      int bitpos = 0;
     label_width = int(maxwidth + 10);  
176      for (int i = 0 ; i < region->Dimensions ; i++) {      for (int i = 0 ; i < region->Dimensions ; i++) {
177          int nbZones = region->pDimensionDefinitions[i].zones;          int nbZones = region->pDimensionDefinitions[i].zones;
178          if (nbZones) {          if (nbZones) {
179              // draw focus rectangle around dimension's label and zones              if (y >= clipy2) break;
180              if (has_focus() && focus_line == i) {              if (y + h > clipy1) {
181                  Gdk::Rectangle farea(0, y, 150, 20);                  // draw focus rectangle around dimension's label and zones
182                  get_style()->paint_focus(window, get_state(), farea, *this, "",                  if (has_focus() && focus_line == i) {
183                                           0, y, label_width, 20);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
184              }                      Gdk::Rectangle farea(0, y, 150, 20);
185                        get_style()->paint_focus(get_window(), get_state(), farea,
186              Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();                                               *this, "",
187              // draw top and bottom lines of dimension's zones                                               0, y, label_width, 20);
188              window->draw_line(black, label_width, y, w - 1, y);  #else
189              window->draw_line(black, w - 1, y + h - 1, label_width, y + h - 1);                      get_style_context()->render_focus(cr,
190              // erase whole dimension's zones area                                                        0, y, label_width, 20);
191              window->draw_rectangle(get_style()->get_white_gc(), true,  #endif
192                                     label_width + 1, y + 1, (w - label_width - 2), h - 2);                  }
193    
194              int c = 0;                  // draw top and bottom lines of dimension's zones
195              if (dimregno >= 0) {                  Gdk::Cairo::set_source_rgba(cr, black);
196                  int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);                  cr->move_to(label_width, y + 0.5);
197                  c = dimregno & mask; // mask away this dimension                  cr->line_to(w, y + 0.5);
198              }                  cr->move_to(w, y + h - 0.5);
199              bool customsplits =                  cr->line_to(label_width, y + h - 0.5);
200                  ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&                  cr->stroke();
201                   region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||  
202                  (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&                  // erase whole dimension's zones area
203                   region->pDimensionRegions[c]->VelocityUpperLimit));                  Gdk::Cairo::set_source_rgba(cr, white);
204                    cr->rectangle(label_width + 1, y + 1,
205                                  (w - label_width - 2), h - 2);
206                    cr->fill();
207    
208                    int c = 0;
209                    if (dimregno >= 0) {
210                        int mask =
211                            ~(((1 << region->pDimensionDefinitions[i].bits) - 1) <<
212                              bitpos);
213                        c = dimregno & mask; // mask away this dimension
214                    }
215                    bool customsplits =
216                        ((region->pDimensionDefinitions[i].split_type ==
217                          gig::split_type_normal &&
218                          region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||
219                         (region->pDimensionDefinitions[i].dimension ==
220                          gig::dimension_velocity &&
221                          region->pDimensionRegions[c]->VelocityUpperLimit));
222    
223              // draw dimension's zone borders                  // draw dimension's zone borders
224              if (customsplits) {                  Gdk::Cairo::set_source_rgba(cr, black);
                 window->draw_line(black, label_width, y + 1, label_width, y + h - 2);  
                 for (int j = 0 ; j < nbZones ; j++) {  
                     gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];  
                     int upperLimit = d->DimensionUpperLimits[i];  
                     if (!upperLimit) upperLimit = d->VelocityUpperLimit;  
                     int v = upperLimit + 1;  
                     int x = int((w - label_width - 1) * v / 128.0 + 0.5);  
                     window->draw_line(black, label_width + x, y + 1, label_width + x, y + h - 2);  
                 }  
             } else {  
                 for (int j = 0 ; j <= nbZones ; j++) {  
                     int x = int((w - label_width - 1) * j / double(nbZones) + 0.5);  
                     window->draw_line(black, label_width + x, y + 1, label_width + x, y + h - 2);  
                 }  
             }  
   
             // draw fill for currently selected zone  
             if (dimregno >= 0) {  
                 gc->set_foreground(red);  
                 int dr = (dimregno >> bitpos) & ((1 << region->pDimensionDefinitions[i].bits) - 1);  
225                  if (customsplits) {                  if (customsplits) {
226                      int x1 = 0;                      cr->move_to(label_width + 0.5, y + 1);
227                        cr->line_to(label_width + 0.5, y + h - 1);
228    
229                      for (int j = 0 ; j < nbZones ; j++) {                      for (int j = 0 ; j < nbZones ; j++) {
230                          gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];                          gig::DimensionRegion* d =
231                                region->pDimensionRegions[c + (j << bitpos)];
232                          int upperLimit = d->DimensionUpperLimits[i];                          int upperLimit = d->DimensionUpperLimits[i];
233                          if (!upperLimit) upperLimit = d->VelocityUpperLimit;                          if (!upperLimit) upperLimit = d->VelocityUpperLimit;
234                          int v = upperLimit + 1;                          int v = upperLimit + 1;
235                          int x2 = int((w - label_width - 1) * v / 128.0 + 0.5);                          int x = int((w - label_width - 1) * v / 128.0 + 0.5) +
236                          if (j == dr && x1 < x2) {                              label_width;
237                              window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1,                          if (x >= clipx2) break;
238                                                     (x2 - x1) - 1, h - 2);                          if (x < clipx1) continue;
239                              break;                          cr->move_to(x + 0.5, y + 1);
240                          }                          cr->line_to(x + 0.5, y + h - 1);
                         x1 = x2;  
241                      }                      }
242                  } else {                  } else {
243                      if (dr < nbZones) {                      for (int j = 0 ; j <= nbZones ; j++) {
244                          int x1 = int((w - label_width - 1) * dr / double(nbZones) + 0.5);                          int x = int((w - label_width - 1) * j /
245                          int x2 = int((w - label_width - 1) * (dr + 1) / double(nbZones) + 0.5);                                      double(nbZones) + 0.5) + label_width;
246                          window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1,                          if (x >= clipx2) break;
247                                                 (x2 - x1) - 1, h - 2);                          if (x < clipx1) continue;
248                            cr->move_to(x + 0.5, y + 1);
249                            cr->line_to(x + 0.5, y + h - 1);
250                        }
251                    }
252                    cr->stroke();
253    
254                    // draw fill for currently selected zone
255                    if (dimregno >= 0) {
256                        Gdk::Cairo::set_source_rgba(cr, red);
257                        int dr = (dimregno >> bitpos) &
258                            ((1 << region->pDimensionDefinitions[i].bits) - 1);
259                        
260                        int x1 = -1, x2 = -1;
261                        if (customsplits) {
262                            x1 = label_width;
263                            for (int j = 0 ; j < nbZones && x1 + 1 < clipx2 ; j++) {
264                                gig::DimensionRegion* d =
265                                    region->pDimensionRegions[c + (j << bitpos)];
266                                int upperLimit = d->DimensionUpperLimits[i];
267                                if (!upperLimit) {
268                                    upperLimit = d->VelocityUpperLimit;
269                                }
270                                int v = upperLimit + 1;
271                                x2 = int((w - label_width - 1) * v / 128.0 +
272                                         0.5) + label_width;
273                                if (j == dr && x1 < x2) {
274                                    cr->rectangle(x1 + 1, y + 1,
275                                                  (x2 - x1) - 1, h - 2);
276                                    cr->fill();
277                                    break;
278                                }
279                                x1 = x2;
280                            }
281                        } else {
282                            if (dr < nbZones) {
283                                x1 = int((w - label_width - 1) * dr /
284                                         double(nbZones) + 0.5);
285                                x2 = int((w - label_width - 1) * (dr + 1) /
286                                         double(nbZones) + 0.5);
287                                cr->rectangle(label_width + x1 + 1, y + 1,
288                                              (x2 - x1) - 1, h - 2);
289                                cr->fill();
290                            }
291                        }
292    
293                        // draw text showing the beginning of the dimension zone
294                        // as numeric value to the user
295                        if (x1 >= 0) {
296                            Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
297                            int v = roundf(float(x1 - label_width) / float(w - label_width) * 127.f);
298                            if (dr > 0) v++;
299                            layout->set_text(Glib::Ascii::dtostr(v));
300                            Gdk::Cairo::set_source_rgba(cr, black);
301                            Pango::Rectangle rect = layout->get_logical_extents();
302                            
303                            int text_width, text_height;
304                            // get the text dimensions
305                            layout->get_pixel_size(text_width, text_height);
306                            // move text to the right end of the dimension zone
307                            cr->move_to(x1 + 1, y + 1);
308    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
309                            pango_cairo_show_layout(cr->cobj(), layout->gobj());
310    #else
311                            layout->show_in_cairo_context(cr);
312    #endif
313                        }
314                        // draw text showing the end of the dimension zone
315                        // as numeric value to the user
316                        if (x2 >= 0) {
317                            Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
318                            const int v = roundf(float(x2 - label_width) / float(w - label_width) * 127.f);
319                            layout->set_text(Glib::Ascii::dtostr(v));
320                            Gdk::Cairo::set_source_rgba(cr, black);
321                            Pango::Rectangle rect = layout->get_logical_extents();
322                            
323                            int text_width, text_height;
324                            // get the text dimensions
325                            layout->get_pixel_size(text_width, text_height);
326                            // move text to the right end of the dimension zone
327                            cr->move_to(x2 - text_width - 1, y + 1);
328    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
329                            pango_cairo_show_layout(cr->cobj(), layout->gobj());
330    #else
331                            layout->show_in_cairo_context(cr);
332    #endif
333                      }                      }
334                  }                  }
335              }              }
# Line 228  bool DimRegionChooser::on_expose_event(G Line 342  bool DimRegionChooser::on_expose_event(G
342      return true;      return true;
343  }  }
344    
 void DimRegionChooser::on_size_request(GtkRequisition* requisition)  
 {  
     *requisition = GtkRequisition();  
     requisition->height = region ? nbDimensions * 20 : 0;  
     requisition->width = 800;  
 }  
   
345  void DimRegionChooser::set_region(gig::Region* region)  void DimRegionChooser::set_region(gig::Region* region)
346  {  {
347      this->region = region;      this->region = region;
# Line 248  void DimRegionChooser::set_region(gig::R Line 355  void DimRegionChooser::set_region(gig::R
355    
356              int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],              int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],
357                               region->pDimensionDefinitions[dim].zones - 1);                               region->pDimensionDefinitions[dim].zones - 1);
             int mask =  
                 ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<  
                   bitcount);  
             dimregno &= mask;  
358              dimregno |= (z << bitcount);              dimregno |= (z << bitcount);
359              bitcount += region->pDimensionDefinitions[dim].bits;              bitcount += region->pDimensionDefinitions[dim].bits;
360          }          }
# Line 260  void DimRegionChooser::set_region(gig::R Line 363  void DimRegionChooser::set_region(gig::R
363          dimreg = 0;          dimreg = 0;
364      }      }
365      dimregion_selected();      dimregion_selected();
366        set_size_request(800, region ? nbDimensions * 20 : 0);
367    
368        labels_changed = true;
369      queue_resize();      queue_resize();
370  }  }
371    
372  bool DimRegionChooser::on_button_release_event(GdkEventButton* event)  
373    void DimRegionChooser::get_dimregions(const gig::Region* region, bool stereo,
374                                          std::set<gig::DimensionRegion*>& dimregs) const
375  {  {
376      if (resize.active) {      int dimregno = 0;
377          get_window()->pointer_ungrab(event->time);      int bitcount = 0;
378          resize.active = false;      int stereo_bit = 0;
379        for (int dim = 0 ; dim < region->Dimensions ; dim++) {
380            if (region->pDimensionDefinitions[dim].bits == 0) continue;
381            if (stereo &&
382                region->pDimensionDefinitions[dim].dimension == gig::dimension_samplechannel) {
383                stereo_bit = (1 << bitcount);
384            } else {
385                int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],
386                                 region->pDimensionDefinitions[dim].zones - 1);
387                dimregno |= (z << bitcount);
388            }
389            bitcount += region->pDimensionDefinitions[dim].bits;
390        }
391        dimregs.insert(region->pDimensionRegions[dimregno]);
392        if (stereo_bit) dimregs.insert(region->pDimensionRegions[dimregno | stereo_bit]);
393    }
394    
395          if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {  void DimRegionChooser::update_after_resize()
396    {
397        if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
398    
399              int bitpos = 0;          int bitpos = 0;
400              for (int j = 0 ; j < resize.dimension ; j++) {          for (int j = 0 ; j < resize.dimension ; j++) {
401                  bitpos += region->pDimensionDefinitions[j].bits;              bitpos += region->pDimensionDefinitions[j].bits;
402            }
403            int mask =
404                ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
405            int c = dimregno & mask; // mask away this dimension
406    
407            if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {
408                // the velocity dimension didn't previously have
409                // custom v3 splits, so we initialize all splits with
410                // default values
411                int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
412                for (int j = 0 ; j < nbZones ; j++) {
413                    gig::DimensionRegion* d = region->pDimensionRegions[c + (j << bitpos)];
414                    d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
415              }              }
416              int mask =          }
417                  ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);          if (region->pDimensionRegions[c]->VelocityUpperLimit == 0) {
418              int c = dimregno & mask; // mask away this dimension              // the velocity dimension didn't previously have
419                // custom v2 splits, so we initialize all splits with
420                // default values
421                int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
422                for (int j = 0 ; j < nbZones ; j++) {
423                    gig::DimensionRegion* d = region->pDimensionRegions[c + (j << bitpos)];
424                    d->VelocityUpperLimit = int(128.0 * (j + 1) / nbZones - 1);
425                }
426            }
427    
428              if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {          gig::DimensionRegion* d = region->pDimensionRegions[c + resize.offset];
429                  // the velocity dimension didn't previously have          // update both v2 and v3 values
430                  // custom v3 splits, so we initialize all splits with          d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
431                  // default values          d->VelocityUpperLimit = resize.pos - 1;
432                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;  
433                  for (int j = 0 ; j < nbZones ; j++) {      } else {
434                      gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];          for (int i = 0 ; i < region->DimensionRegions ; ) {
435                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);  
436                if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {
437                    // the dimension didn't previously have custom
438                    // limits, so we have to set default limits for
439                    // all the dimension regions
440                    int bitpos = 0;
441                    for (int j = 0 ; j < resize.dimension ; j++) {
442                        bitpos += region->pDimensionDefinitions[j].bits;
443                  }                  }
             }  
             if (region->pDimensionRegions[c]->VelocityUpperLimit == 0) {  
                 // the velocity dimension didn't previously have  
                 // custom v2 splits, so we initialize all splits with  
                 // default values  
444                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
445    
446                  for (int j = 0 ; j < nbZones ; j++) {                  for (int j = 0 ; j < nbZones ; j++) {
447                      gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];                      gig::DimensionRegion* d = region->pDimensionRegions[i + (j << bitpos)];
448                      d->VelocityUpperLimit = int(128.0 * (j + 1) / nbZones - 1);                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
449                  }                  }
450              }              }
451                gig::DimensionRegion* d = region->pDimensionRegions[i + resize.offset];
             gig::DimensionRegion *d = region->pDimensionRegions[c + resize.offset];  
             // update both v2 and v3 values  
452              d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;              d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
             d->VelocityUpperLimit = resize.pos - 1;  
   
         } else {  
             for (int i = 0 ; i < region->DimensionRegions ; ) {  
   
                 if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {  
                     // the dimension didn't previously have custom  
                     // limits, so we have to set default limits for  
                     // all the dimension regions  
                     int bitpos = 0;  
                     for (int j = 0 ; j < resize.dimension ; j++) {  
                         bitpos += region->pDimensionDefinitions[j].bits;  
                     }  
                     int nbZones = region->pDimensionDefinitions[resize.dimension].zones;  
   
                     for (int j = 0 ; j < nbZones ; j++) {  
                         gig::DimensionRegion *d = region->pDimensionRegions[i + (j << bitpos)];  
                         d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);  
                     }  
                 }  
                 gig::DimensionRegion *d = region->pDimensionRegions[i + resize.offset];  
                 d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;  
453    
454                  int bitpos = 0;              int bitpos = 0;
455                  int j;              int j;
456                  for (j = 0 ; j < region->Dimensions ; j++) {              for (j = 0 ; j < region->Dimensions ; j++) {
457                      if (j != resize.dimension) {                  if (j != resize.dimension) {
458                          int maxzones = 1 << region->pDimensionDefinitions[j].bits;                      int maxzones = 1 << region->pDimensionDefinitions[j].bits;
459                          int dimj = (i >> bitpos) & (maxzones - 1);                      int dimj = (i >> bitpos) & (maxzones - 1);
460                          if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;                      if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;
                     }  
                     bitpos += region->pDimensionDefinitions[j].bits;  
461                  }                  }
462                  if (j == region->Dimensions) break;                  bitpos += region->pDimensionDefinitions[j].bits;
                 i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);  
463              }              }
464                if (j == region->Dimensions) break;
465                i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
466          }          }
467        }
468    }
469    
470    bool DimRegionChooser::on_button_release_event(GdkEventButton* event)
471    {
472        if (resize.active) {
473    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
474            get_window()->pointer_ungrab(event->time);
475    #else
476            Glib::wrap(event->device, true)->ungrab(event->time);
477    #endif
478            resize.active = false;
479    
480          region_changed();          region_changed();
481    
482          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
# Line 352  bool DimRegionChooser::on_button_release Line 489  bool DimRegionChooser::on_button_release
489    
490  bool DimRegionChooser::on_button_press_event(GdkEventButton* event)  bool DimRegionChooser::on_button_press_event(GdkEventButton* event)
491  {  {
492        int w = get_width();
493      if (region && event->y < nbDimensions * h &&      if (region && event->y < nbDimensions * h &&
494          event->x >= label_width && event->x < w) {          event->x >= label_width && event->x < w) {
495    
496          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
497              Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
498              get_window()->pointer_grab(false,              get_window()->pointer_grab(false,
499                                         Gdk::BUTTON_RELEASE_MASK |                                         Gdk::BUTTON_RELEASE_MASK |
500                                         Gdk::POINTER_MOTION_MASK |                                         Gdk::POINTER_MOTION_MASK |
501                                         Gdk::POINTER_MOTION_HINT_MASK,                                         Gdk::POINTER_MOTION_HINT_MASK,
502                                         double_arrow, event->time);                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW),
503                                           event->time);
504    #else
505                Glib::wrap(event->device, true)->grab(get_window(),
506                                                      Gdk::OWNERSHIP_NONE,
507                                                      false,
508                                                      Gdk::BUTTON_RELEASE_MASK |
509                                                      Gdk::POINTER_MOTION_MASK |
510                                                      Gdk::POINTER_MOTION_HINT_MASK,
511                                                      Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW),
512                                                      event->time);
513    #endif
514              resize.active = true;              resize.active = true;
515          } else {          } else {
516              int ydim = int(event->y / h);              int ydim = int(event->y / h);
# Line 394  bool DimRegionChooser::on_button_press_e Line 543  bool DimRegionChooser::on_button_press_e
543    
544                  if (region->pDimensionRegions[c]->DimensionUpperLimits[i]) {                  if (region->pDimensionRegions[c]->DimensionUpperLimits[i]) {
545                      for (z = 0 ; z < nbZones ; z++) {                      for (z = 0 ; z < nbZones ; z++) {
546                          gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];                          gig::DimensionRegion* d = region->pDimensionRegions[c + (z << bitpos)];
547                          if (val <= d->DimensionUpperLimits[i]) break;                          if (val <= d->DimensionUpperLimits[i]) break;
548                      }                      }
549                  } else {                  } else {
550                      for (z = 0 ; z < nbZones ; z++) {                      for (z = 0 ; z < nbZones ; z++) {
551                          gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];                          gig::DimensionRegion* d = region->pDimensionRegions[c + (z << bitpos)];
552                          if (val <= d->VelocityUpperLimit) break;                          if (val <= d->VelocityUpperLimit) break;
553                      }                      }
554                  }                  }
# Line 434  bool DimRegionChooser::on_motion_notify_ Line 583  bool DimRegionChooser::on_motion_notify_
583      window->get_pointer(x, y, state);      window->get_pointer(x, y, state);
584    
585      if (resize.active) {      if (resize.active) {
586            int w = get_width();
587          int k = int((x - label_width) * 128.0 / (w - label_width - 1) + 0.5);          int k = int((x - label_width) * 128.0 / (w - label_width - 1) + 0.5);
588    
589          if (k < resize.min) k = resize.min;          if (k < resize.min) k = resize.min;
# Line 442  bool DimRegionChooser::on_motion_notify_ Line 592  bool DimRegionChooser::on_motion_notify_
592          if (k < 2) k = 2; // k is upper limit + 1, upper limit 0 is forbidden          if (k < 2) k = 2; // k is upper limit + 1, upper limit 0 is forbidden
593    
594          if (k != resize.pos) {          if (k != resize.pos) {
             Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();  
             Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();  
   
595              int prevx = int((w - label_width - 1) * resize.pos / 128.0 + 0.5) + label_width;              int prevx = int((w - label_width - 1) * resize.pos / 128.0 + 0.5) + label_width;
596              int x = int((w - label_width - 1) * k / 128.0 + 0.5) + label_width;              int x = int((w - label_width - 1) * k / 128.0 + 0.5) + label_width;
597              int y = resize.dimension * h;              int y = resize.dimension * h;
598                int x1, x2;
599              if (resize.selected == resize.none) {              if (k > resize.pos) {
600                  if (resize.pos != resize.min && resize.pos != resize.max) {                  x1 = prevx;
601                      window->draw_line(white, prevx, y + 1, prevx, y + h - 2);                  x2 = x;
                 }  
602              } else {              } else {
603                  gc->set_foreground(red);                  x1 = x;
604                    x2 = prevx;
                 Glib::RefPtr<const Gdk::GC> left;  
                 Glib::RefPtr<const Gdk::GC> right;  
                 if (resize.selected == resize.left) {  
                     left = gc;  
                     right = white;  
                 } else {  
                     left = white;  
                     right = gc;  
                 }  
   
                 if (k > resize.pos) {  
                     int xx = resize.pos == resize.min ? 1 : 0;  
                     window->draw_rectangle(left, true,  
                                            prevx + xx, y + 1, x - prevx - xx, h - 2);  
                 } else {  
                     int xx = resize.pos == resize.max ? 0 : 1;  
                     window->draw_rectangle(right, true,  
                                            x, y + 1, prevx - x + xx, h - 2);  
                 }  
605              }              }
606              window->draw_line(black, x, y + 1, x, y + h - 2);              Gdk::Rectangle rect(x1, y + 1, x2 - x1 + 1, h - 2);
607    
608              resize.pos = k;              resize.pos = k;
609                update_after_resize();
610                get_window()->invalidate_rect(rect, false);
611          }          }
612      } else {      } else {
613          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
614              if (!cursor_is_resize) {              if (!cursor_is_resize) {
615                  Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
616                  window->set_cursor(double_arrow);                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
617    #else
618                    window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
619    #endif
620                  cursor_is_resize = true;                  cursor_is_resize = true;
621              }              }
622          } else if (cursor_is_resize) {          } else if (cursor_is_resize) {
# Line 496  bool DimRegionChooser::on_motion_notify_ Line 629  bool DimRegionChooser::on_motion_notify_
629    
630  bool DimRegionChooser::is_in_resize_zone(double x, double y)  bool DimRegionChooser::is_in_resize_zone(double x, double y)
631  {  {
632        int w = get_width();
633      if (region && y < nbDimensions * h && x >= label_width && x < w) {      if (region && y < nbDimensions * h && x >= label_width && x < w) {
634          int ydim = int(y / h);          int ydim = int(y / h);
635          int dim;          int dim;
# Line 523  bool DimRegionChooser::is_in_resize_zone Line 657  bool DimRegionChooser::is_in_resize_zone
657          if (region->pDimensionDefinitions[dim].split_type != gig::split_type_bit) {          if (region->pDimensionDefinitions[dim].split_type != gig::split_type_bit) {
658              int prev_limit = 0;              int prev_limit = 0;
659              for (int iZone = 0 ; iZone < nbZones - 1 ; iZone++) {              for (int iZone = 0 ; iZone < nbZones - 1 ; iZone++) {
660                  gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];                  gig::DimensionRegion* d = region->pDimensionRegions[c + (iZone << bitpos)];
661                  const int upperLimit =                  const int upperLimit =
662                      (customsplits) ?                      (customsplits) ?
663                          (d->DimensionUpperLimits[dim]) ?                          (d->DimensionUpperLimits[dim]) ?
# Line 544  bool DimRegionChooser::is_in_resize_zone Line 678  bool DimRegionChooser::is_in_resize_zone
678                          dr == iZone + 1 ? resize.right : resize.none;                          dr == iZone + 1 ? resize.right : resize.none;
679    
680                      iZone++;                      iZone++;
681                      gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];                      gig::DimensionRegion* d = region->pDimensionRegions[c + (iZone << bitpos)];
682    
683                      const int upperLimit =                      const int upperLimit =
684                          (customsplits) ?                          (customsplits) ?

Legend:
Removed from v.1420  
changed lines
  Added in v.2462

  ViewVC Help
Powered by ViewVC