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

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

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

gigedit/branches/linuxsampler_org/src/dimregionchooser.cpp revision 1052 by persson, Sat Mar 3 12:20:01 2007 UTC gigedit/trunk/src/dimregionchooser.cpp revision 1197 by persson, Fri May 18 16:07:18 2007 UTC
# Line 18  Line 18 
18   */   */
19    
20  #include "dimregionchooser.h"  #include "dimregionchooser.h"
21    #include <gdkmm/cursor.h>
22    
23  DimRegionChooser::DimRegionChooser()  DimRegionChooser::DimRegionChooser()
24  {  {
# Line 40  DimRegionChooser::DimRegionChooser() Line 41  DimRegionChooser::DimRegionChooser()
41      region = 0;      region = 0;
42      dimregno = -1;      dimregno = -1;
43      focus_line = 0;      focus_line = 0;
44        resize.active = false;
45        cursor_is_resize = false;
46        h = 20;
47        w = 800;
48      set_flags(Gtk::CAN_FOCUS);      set_flags(Gtk::CAN_FOCUS);
49      add_events(Gdk::BUTTON_PRESS_MASK);      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |
50                   Gdk::POINTER_MOTION_HINT_MASK);
51    
52      for (int i = 0 ; i < 256 ; i++) {      for (int i = 0 ; i < 256 ; i++) {
53          dimvalue_from[i] = 0;          dimvalue_from[i] = 0;
# Line 67  bool DimRegionChooser::on_expose_event(G Line 73  bool DimRegionChooser::on_expose_event(G
73  {  {
74      if (!region) return true;      if (!region) return true;
75    
     int a = 1, b, c;  
     for (int i = 0 ; i < region->Dimensions ; i++) {  
         b = a * region->pDimensionDefinitions[i].zones;  
         if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity) {  
             c = dimregno >= 0 ? (dimregno & ((a - 1) | ~(b - 1))) : 0;  
             break;  
         }  
         a = b;  
     }  
   
76      // This is where we draw on the window      // This is where we draw on the window
77      Glib::RefPtr<Gdk::Window> window = get_window();      Glib::RefPtr<Gdk::Window> window = get_window();
78      Glib::RefPtr<Pango::Context> context = get_pango_context();      Glib::RefPtr<Pango::Context> context = get_pango_context();
# Line 84  bool DimRegionChooser::on_expose_event(G Line 80  bool DimRegionChooser::on_expose_event(G
80      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
81    
82      window->clear();      window->clear();
     const int h = 20;  
     const int w = 800;  
     const int w1 = 100;  
83      int y = 0;      int y = 0;
84      int bitcount = 0;      double maxwidth = 0;
85      for (int i = 0 ; i < region->Dimensions ; i++) {      for (int i = 0 ; i < region->Dimensions ; i++) {
86          const int nb = region->pDimensionDefinitions[i].zones;  
87          if (nb) {          int nbZones = region->pDimensionDefinitions[i].zones;
88            if (nbZones) {
89              char* dstr;              char* dstr;
90                char dstrbuf[10];
91              switch (region->pDimensionDefinitions[i].dimension) {              switch (region->pDimensionDefinitions[i].dimension) {
92              case gig::dimension_none: dstr="none"; break;              case gig::dimension_none: dstr="none"; break;
93              case gig::dimension_samplechannel: dstr="samplechannel"; break;              case gig::dimension_samplechannel: dstr="samplechannel"; break;
# Line 103  bool DimRegionChooser::on_expose_event(G Line 98  bool DimRegionChooser::on_expose_event(G
98              case gig::dimension_keyboard: dstr="keyboard"; break;              case gig::dimension_keyboard: dstr="keyboard"; break;
99              case gig::dimension_roundrobin: dstr="roundrobin"; break;              case gig::dimension_roundrobin: dstr="roundrobin"; break;
100              case gig::dimension_random: dstr="random"; break;              case gig::dimension_random: dstr="random"; break;
101                case gig::dimension_smartmidi: dstr="smartmidi"; break;
102                case gig::dimension_roundrobinkeyboard: dstr="roundrobinkeyboard"; break;
103              case gig::dimension_modwheel: dstr="modwheel"; break;              case gig::dimension_modwheel: dstr="modwheel"; break;
104              case gig::dimension_breath: dstr="breath"; break;              case gig::dimension_breath: dstr="breath"; break;
105              case gig::dimension_foot: dstr="foot"; break;              case gig::dimension_foot: dstr="foot"; break;
# Line 126  bool DimRegionChooser::on_expose_event(G Line 123  bool DimRegionChooser::on_expose_event(G
123              case gig::dimension_effect3depth: dstr="effect3depth"; break;              case gig::dimension_effect3depth: dstr="effect3depth"; break;
124              case gig::dimension_effect4depth: dstr="effect4depth"; break;              case gig::dimension_effect4depth: dstr="effect4depth"; break;
125              case gig::dimension_effect5depth: dstr="effect5depth"; break;              case gig::dimension_effect5depth: dstr="effect5depth"; break;
126                default:
127                    sprintf(dstrbuf, "%d",
128                            region->pDimensionDefinitions[i].dimension);
129                    dstr = dstrbuf;
130                    break;
131              }              }
132              layout->set_text(dstr);              layout->set_text(dstr);
133    
134              Pango::Rectangle rectangle = layout->get_logical_extents();              Pango::Rectangle rectangle = layout->get_logical_extents();
135              double text_h = double(rectangle.get_height()) / Pango::SCALE;              double text_w = double(rectangle.get_width()) / Pango::SCALE;
136                if (text_w > maxwidth) maxwidth = text_w;
137                double text_h = double(rectangle.get_height()) / Pango::SCALE;
138              Glib::RefPtr<const Gdk::GC> fg = get_style()->get_fg_gc(get_state());              Glib::RefPtr<const Gdk::GC> fg = get_style()->get_fg_gc(get_state());
139              window->draw_layout(fg, 4, int(y + (h - text_h) / 2 + 0.5), layout);              window->draw_layout(fg, 4, int(y + (h - text_h) / 2 + 0.5), layout);
140    
141            }
142            y += h;
143        }
144        y = 0;
145        int bitpos = 0;
146        label_width = int(maxwidth + 10);
147        for (int i = 0 ; i < region->Dimensions ; i++) {
148            int nbZones = region->pDimensionDefinitions[i].zones;
149            if (nbZones) {
150    
151              if (has_focus() && focus_line == i) {              if (has_focus() && focus_line == i) {
152                  Gdk::Rectangle farea(0, y, 50, 20);                  Gdk::Rectangle farea(0, y, 150, 20);
153                  get_style()->paint_focus(window, get_state(), farea, *this, "hejsan", 0, y, 50, 20);                  get_style()->paint_focus(window, get_state(), farea, *this, "",
154                                             0, y, label_width, 20);
155              }              }
156    
157              Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();              Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
158              window->draw_line(black, w1, y, w - 1, y);              window->draw_line(black, label_width, y, w - 1, y);
159              window->draw_line(black, w - 1, y + h - 1, w1, y + h - 1);              window->draw_line(black, w - 1, y + h - 1, label_width, y + h - 1);
160              window->draw_rectangle(get_style()->get_white_gc(), true, w1 + 1, y + 1, (w - w1 - 2), h - 2);              window->draw_rectangle(get_style()->get_white_gc(), true,
161                                       label_width + 1, y + 1, (w - label_width - 2), h - 2);
162              if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&  
163                  region->pDimensionRegions[c]->VelocityUpperLimit) {              int c = 0;
164                  window->draw_line(black, w1, y + 1, w1, y + h - 2);              if (dimregno >= 0) {
165                  for (int k = c ; k < b ; k += a) {                  int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);
166                      gig::DimensionRegion *d = region->pDimensionRegions[k];                  c = dimregno & mask; // mask away this dimension
167                      int v = d->VelocityUpperLimit + 1;              }
168                      int x = int((w - w1 - 1) * v / 128.0 + 0.5);              bool customsplits =
169                      window->draw_line(black, w1 + x, y + 1, w1 + x, y + h - 2);                  ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&
170                     region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||
171                    (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&
172                     region->pDimensionRegions[c]->VelocityUpperLimit));
173    
174                if (customsplits) {
175                    window->draw_line(black, label_width, y + 1, label_width, y + h - 2);
176                    for (int j = 0 ; j < nbZones ; j++) {
177                        gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
178                        int upperLimit = d->DimensionUpperLimits[i];
179                        if (!upperLimit) upperLimit = d->VelocityUpperLimit;
180                        int v = upperLimit + 1;
181                        int x = int((w - label_width - 1) * v / 128.0 + 0.5);
182                        window->draw_line(black, label_width + x, y + 1, label_width + x, y + h - 2);
183                  }                  }
184              } else {              } else {
185                  for (int j = 0 ; j <= nb ; j++) {                  for (int j = 0 ; j <= nbZones ; j++) {
186                      int x = int((w - w1 - 1) * j / double(nb) + 0.5);                      int x = int((w - label_width - 1) * j / double(nbZones) + 0.5);
187                      window->draw_line(black, w1 + x, y + 1, w1 + x, y + h - 2);                      window->draw_line(black, label_width + x, y + 1, label_width + x, y + h - 2);
188                  }                  }
189              }              }
190    
191              if (dimregno >= 0) {              if (dimregno >= 0) {
192                  gc->set_foreground(red);                  gc->set_foreground(red);
193                  int dr = (dimregno >> bitcount) & ((1 << region->pDimensionDefinitions[i].bits) - 1);                  int dr = (dimregno >> bitpos) & ((1 << region->pDimensionDefinitions[i].bits) - 1);
194                  if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&                  if (customsplits) {
195                      region->pDimensionRegions[c]->VelocityUpperLimit) {                      int x1 = 0;
196                      int x1 = 0, dr2 = 0;                      for (int j = 0 ; j < nbZones ; j++) {
197                      for (int k = c ; k < b ; k += a) {                          gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
198                          gig::DimensionRegion *d = region->pDimensionRegions[k];                          int upperLimit = d->DimensionUpperLimits[i];
199                          int v = d->VelocityUpperLimit + 1;                          if (!upperLimit) upperLimit = d->VelocityUpperLimit;
200                          int x2 = int((w - w1 - 1) * v / 128.0 + 0.5);                          int v = upperLimit + 1;
201                          if (dr2 == dr) {                          int x2 = int((w - label_width - 1) * v / 128.0 + 0.5);
202                              window->draw_rectangle(gc, true, w1 + x1 + 1, y + 1, (x2 - x1) - 1, h - 2);                          if (j == dr && x1 < x2) {
203                                window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1,
204                                                       (x2 - x1) - 1, h - 2);
205                              break;                              break;
206                          }                          }
                         dr2++;  
207                          x1 = x2;                          x1 = x2;
208                      }                      }
209                  } else {                  } else {
210                      if (dr < nb) {                      if (dr < nbZones) {
211                          int x1 = int((w - w1 - 1) * dr / double(nb) + 0.5);                          int x1 = int((w - label_width - 1) * dr / double(nbZones) + 0.5);
212                          int x2 = int((w - w1 - 1) * (dr + 1) / double(nb) + 0.5);                          int x2 = int((w - label_width - 1) * (dr + 1) / double(nbZones) + 0.5);
213                          window->draw_rectangle(gc, true, w1 + x1 + 1, y + 1, (x2 - x1) - 1, h - 2);                          window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1,
214                                                   (x2 - x1) - 1, h - 2);
215                      }                      }
216                  }                  }
217              }              }
218    
219              y += h;              y += h;
220          }          }
221          bitcount += region->pDimensionDefinitions[i].bits;          bitpos += region->pDimensionDefinitions[i].bits;
222      }      }
223    
224      return true;      return true;
225  }  }
226    
   
227  void DimRegionChooser::on_size_request(GtkRequisition* requisition)  void DimRegionChooser::on_size_request(GtkRequisition* requisition)
228  {  {
229      printf("DimRegionChooser::on_size_request\n");      printf("DimRegionChooser::on_size_request\n");
230      *requisition = GtkRequisition();      *requisition = GtkRequisition();
231      requisition->height = region ? region->Dimensions * 20 : 0;      requisition->height = region ? nbDimensions * 20 : 0;
232      requisition->width = 800;      requisition->width = 800;
233  }  }
234    
 void DimRegionChooser::set_instrument(gig::Instrument* instrument)  
 {  
     this->instrument = instrument;  
     this->region = 0;  
     this->dimregno = -1;  
     queue_draw();  
 }  
   
235  void DimRegionChooser::set_region(gig::Region* region)  void DimRegionChooser::set_region(gig::Region* region)
236  {  {
237      this->region = region;      this->region = region;
238      dimregno = 0;      dimregno = 0;
239      int bitcount = 0;      nbDimensions = 0;
240      for (int dim = 0 ; dim < region->Dimensions ; dim++) {      if (region) {
241          int from = dimvalue_from[region->pDimensionDefinitions[dim].dimension];          int bitcount = 0;
242          int to = dimvalue_to[region->pDimensionDefinitions[dim].dimension];          for (int dim = 0 ; dim < region->Dimensions ; dim++) {
243          int z;              if (region->pDimensionDefinitions[dim].bits == 0) continue;
244          switch (region->pDimensionDefinitions[dim].split_type) {              nbDimensions++;
245          case gig::split_type_normal:  
246              z = int((to + from) / 2.0 / region->pDimensionDefinitions[dim].zone_size);              int from = dimvalue_from[region->pDimensionDefinitions[dim].dimension];
247              break;              int to = dimvalue_to[region->pDimensionDefinitions[dim].dimension];
248          case gig::split_type_bit:              int z;
249              z = std::min(from, region->pDimensionDefinitions[dim].zones - 1);              switch (region->pDimensionDefinitions[dim].split_type) {
250              break;              case gig::split_type_normal:
251          }                  z = int((to + from) / 2.0 / region->pDimensionDefinitions[dim].zone_size);
252          int mask =                  break;
253              ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<              case gig::split_type_bit:
254                bitcount);                  z = std::min(from, region->pDimensionDefinitions[dim].zones - 1);
255          dimregno &= mask;                  break;
256          dimregno |= (z << bitcount);              }
257          bitcount += region->pDimensionDefinitions[dim].bits;              int mask =
258                    ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<
259                      bitcount);
260                dimregno &= mask;
261                dimregno |= (z << bitcount);
262                bitcount += region->pDimensionDefinitions[dim].bits;
263            }
264            dimreg = region->pDimensionRegions[dimregno];
265        } else {
266            dimreg = 0;
267      }      }
     dimreg = region->pDimensionRegions[dimregno];  
268      sel_changed_signal.emit();      sel_changed_signal.emit();
269      queue_resize();      queue_resize();
270  }  }
271    
272  /*  bool DimRegionChooser::on_button_release_event(GdkEventButton* event)
   void DimRegionChooser::set_dimregno(int x) {  
   this->dimregno = x;  
   queue_draw();  
   }  
 */  
   
 bool DimRegionChooser::on_button_press_event(GdkEventButton* event)  
273  {  {
274      const int h = 20;      if (resize.active) {
275      const int w = 800;          get_window()->pointer_ungrab(event->time);
276      const int w1 = 100;          resize.active = false;
277    
278            if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
279    
280                int bitpos = 0;
281                for (int j = 0 ; j < resize.dimension ; j++) {
282                    bitpos += region->pDimensionDefinitions[j].bits;
283                }
284                int mask =
285                    ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
286                int c = dimregno & mask; // mask away this dimension
287    
288      if (region) {              if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {
289          if (event->y < region->Dimensions * h &&                  // the velocity dimension didn't previously have
290              event->x >= w1 && event->x < w) {                  // custom v3 splits, so we initialize all splits with
291                    // default values
292                    int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
293                    for (int j = 0 ; j < nbZones ; j++) {
294                        gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
295                        d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
296                    }
297                }
298                if (region->pDimensionRegions[c]->VelocityUpperLimit == 0) {
299                    // the velocity dimension didn't previously have
300                    // custom v2 splits, so we initialize all splits with
301                    // default values
302                    int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
303                    for (int j = 0 ; j < nbZones ; j++) {
304                        gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
305                        d->VelocityUpperLimit = int(128.0 * (j + 1) / nbZones - 1);
306                    }
307                }
308    
309              int dim = int(event->y / h);              gig::DimensionRegion *d = region->pDimensionRegions[c + resize.offset];
310              const int nb = region->pDimensionDefinitions[dim].zones;              // update both v2 and v3 values
311                d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
312                d->VelocityUpperLimit = resize.pos - 1;
313    
314            } else {
315                for (int i = 0 ; i < region->DimensionRegions ; ) {
316    
317                    if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {
318                        // the dimension didn't previously have custom
319                        // limits, so we have to set default limits for
320                        // all the dimension regions
321                        int bitpos = 0;
322                        for (int j = 0 ; j < resize.dimension ; j++) {
323                            bitpos += region->pDimensionDefinitions[j].bits;
324                        }
325                        int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
326    
327              int z = -1;                      for (int j = 0 ; j < nbZones ; j++) {
328              if (region->pDimensionDefinitions[dim].dimension == gig::dimension_velocity) {                          gig::DimensionRegion *d = region->pDimensionRegions[i + (j << bitpos)];
329                  int a = 1, b, c;                          d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
                 for (int i = 0 ; i < region->Dimensions ; i++) {  
                     b = a * region->pDimensionDefinitions[i].zones;  
                     if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity) {  
                         c = dimregno >= 0 ? (dimregno & ((a - 1) | ~(b - 1))) : 0;  
                         break;  
330                      }                      }
                     a = b;  
331                  }                  }
332                    gig::DimensionRegion *d = region->pDimensionRegions[i + resize.offset];
333                    d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
334    
335                  if (region->pDimensionRegions[c]->VelocityUpperLimit) {                  int bitpos = 0;
336                      int vel = int((event->x - w1) * 128 / (w - w1 - 1));                  int j;
337                    for (j = 0 ; j < region->Dimensions ; j++) {
338                      z = 0;                      if (j != resize.dimension) {
339                      for (int k = c ; k < b ; k += a) {                          int maxzones = 1 << region->pDimensionDefinitions[j].bits;
340                          gig::DimensionRegion *d = region->pDimensionRegions[k];                          int dimj = (i >> bitpos) & (maxzones - 1);
341                          if (vel <= d->VelocityUpperLimit) break;                          if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;
                         z++;  
342                      }                      }
343                        bitpos += region->pDimensionDefinitions[j].bits;
344                  }                  }
345                    if (j == region->Dimensions) break;
346                    i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
347              }              }
348            }
349    
350            if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
351                get_window()->set_cursor();
352                cursor_is_resize = false;
353            }
354        }
355        return true;
356    }
357    
358              if (z == -1) {  bool DimRegionChooser::on_button_press_event(GdkEventButton* event)
359                  z = int((event->x - w1) * nb / (w - w1 - 1));  {
360        if (region && event->y < nbDimensions * h &&
361            event->x >= label_width && event->x < w) {
362    
363            if (is_in_resize_zone(event->x, event->y)) {
364                Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
365                get_window()->pointer_grab(false,
366                                           Gdk::BUTTON_RELEASE_MASK |
367                                           Gdk::POINTER_MOTION_MASK |
368                                           Gdk::POINTER_MOTION_HINT_MASK,
369                                           double_arrow, event->time);
370                resize.active = true;
371            } else {
372                int ydim = int(event->y / h);
373                int dim;
374                for (dim = 0 ; dim < region->Dimensions ; dim++) {
375                    if (region->pDimensionDefinitions[dim].bits == 0) continue;
376                    if (ydim == 0) break;
377                    ydim--;
378                }
379                int nbZones = region->pDimensionDefinitions[dim].zones;
380    
381                int z = -1;
382                int bitpos = 0;
383                for (int i = 0 ; i < dim ; i++) {
384                    bitpos += region->pDimensionDefinitions[i].bits;
385                }
386    
387                int i = dim;
388                if (dimregno < 0) dimregno = 0;
389                int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);
390                int c = dimregno & mask; // mask away this dimension
391    
392                bool customsplits =
393                    ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&
394                      region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||
395                     (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&
396                      region->pDimensionRegions[c]->VelocityUpperLimit));
397                if (customsplits) {
398                    int val = int((event->x - label_width) * 128 / (w - label_width - 1));
399    
400                    if (region->pDimensionRegions[c]->DimensionUpperLimits[i]) {
401                        for (z = 0 ; z < nbZones ; z++) {
402                            gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];
403                            if (val <= d->DimensionUpperLimits[i]) break;
404                        }
405                    } else {
406                        for (z = 0 ; z < nbZones ; z++) {
407                            gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];
408                            if (val <= d->VelocityUpperLimit) break;
409                        }
410                    }
411                } else {
412                    z = int((event->x - label_width) * nbZones / (w - label_width - 1));
413              }              }
414    
415              printf("dim=%d z=%d dimensionsource=%d split_type=%d zones=%d zone_size=%f\n", dim, z,              printf("dim=%d z=%d dimensionsource=%d split_type=%d zones=%d zone_size=%f\n", dim, z,
# Line 293  bool DimRegionChooser::on_button_press_e Line 417  bool DimRegionChooser::on_button_press_e
417                     region->pDimensionDefinitions[dim].split_type,                     region->pDimensionDefinitions[dim].split_type,
418                     region->pDimensionDefinitions[dim].zones,                     region->pDimensionDefinitions[dim].zones,
419                     region->pDimensionDefinitions[dim].zone_size);                     region->pDimensionDefinitions[dim].zone_size);
420    #if 0
421              switch (region->pDimensionDefinitions[dim].split_type) {              switch (region->pDimensionDefinitions[dim].split_type) {
422              case gig::split_type_normal:              case gig::split_type_normal:
423                  dimvalue_from[region->pDimensionDefinitions[dim].dimension] =                  dimvalue_from[region->pDimensionDefinitions[dim].dimension] =
# Line 305  bool DimRegionChooser::on_button_press_e Line 430  bool DimRegionChooser::on_button_press_e
430                  dimvalue_to[region->pDimensionDefinitions[dim].dimension] = z + 1;                  dimvalue_to[region->pDimensionDefinitions[dim].dimension] = z + 1;
431                  break;                  break;
432              }              }
433              if (dimregno < 0) dimregno = 0;  #endif
             int bitcount = 0;  
             for (int i = 0 ; i < dim ; i++) {  
                 bitcount += region->pDimensionDefinitions[i].bits;  
             }  
434    
435              int mask =              dimregno = c | (z << bitpos);
                 ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<  
                   bitcount);  
             dimregno &= mask;  
             dimregno |= (z << bitcount);  
436    
437              focus_line = dim;              focus_line = dim;
438              if (has_focus()) queue_draw();              if (has_focus()) queue_draw();
# Line 327  bool DimRegionChooser::on_button_press_e Line 444  bool DimRegionChooser::on_button_press_e
444      return true;      return true;
445  }  }
446    
447    bool DimRegionChooser::on_motion_notify_event(GdkEventMotion* event)
448    {
449        Glib::RefPtr<Gdk::Window> window = get_window();
450        int x, y;
451        Gdk::ModifierType state = Gdk::ModifierType(0);
452        window->get_pointer(x, y, state);
453    
454        if (resize.active) {
455            int k = int((x - label_width) * 128.0 / (w - label_width - 1) + 0.5);
456    
457            if (k < resize.min) k = resize.min;
458            else if (k > resize.max) k = resize.max;
459    
460            if (k < 2) k = 2; // k is upper limit + 1, upper limit 0 is forbidden
461    
462            if (k != resize.pos) {
463                Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
464                Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();
465    
466                int prevx = int((w - label_width - 1) * resize.pos / 128.0 + 0.5) + label_width;
467                int x = int((w - label_width - 1) * k / 128.0 + 0.5) + label_width;
468                int y = resize.dimension * h;
469    
470                if (resize.selected == resize.none) {
471                    if (resize.pos != resize.min && resize.pos != resize.max) {
472                        window->draw_line(white, prevx, y + 1, prevx, y + h - 2);
473                    }
474                } else {
475                    gc->set_foreground(red);
476    
477                    Glib::RefPtr<const Gdk::GC> left;
478                    Glib::RefPtr<const Gdk::GC> right;
479                    if (resize.selected == resize.left) {
480                        left = gc;
481                        right = white;
482                    } else {
483                        left = white;
484                        right = gc;
485                    }
486    
487                    if (k > resize.pos) {
488                        int xx = resize.pos == resize.min ? 1 : 0;
489                        window->draw_rectangle(left, true,
490                                               prevx + xx, y + 1, x - prevx - xx, h - 2);
491                    } else {
492                        int xx = resize.pos == resize.max ? 0 : 1;
493                        window->draw_rectangle(right, true,
494                                               x, y + 1, prevx - x + xx, h - 2);
495                    }
496                }
497                window->draw_line(black, x, y + 1, x, y + h - 2);
498                resize.pos = k;
499            }
500        } else {
501            if (is_in_resize_zone(x, y)) {
502                if (!cursor_is_resize) {
503                    Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
504                    window->set_cursor(double_arrow);
505                    cursor_is_resize = true;
506                }
507            } else if (cursor_is_resize) {
508                window->set_cursor();
509                cursor_is_resize = false;
510            }
511        }
512        return true;
513    }
514    
515    bool DimRegionChooser::is_in_resize_zone(double x, double y)
516    {
517        if (region && y < nbDimensions * h && x >= label_width && x < w) {
518            int ydim = int(y / h);
519            int dim;
520            int bitpos = 0;
521            for (dim = 0 ; dim < region->Dimensions ; dim++) {
522                if (region->pDimensionDefinitions[dim].bits == 0) continue;
523                if (ydim == 0) break;
524                ydim--;
525                bitpos += region->pDimensionDefinitions[dim].bits;
526            }
527            int nbZones = region->pDimensionDefinitions[dim].zones;
528    
529            int c = 0;
530            if (dimregno >= 0) {
531                int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);
532                c = dimregno & mask; // mask away this dimension
533            }
534            const bool customsplits =
535                ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&
536                  region->pDimensionRegions[c]->DimensionUpperLimits[dim]) ||
537                 (region->pDimensionDefinitions[dim].dimension == gig::dimension_velocity &&
538                  region->pDimensionRegions[c]->VelocityUpperLimit));
539    
540            // dimensions of split_type_bit cannot be resized
541            if (region->pDimensionDefinitions[dim].split_type != gig::split_type_bit) {
542                int prev_limit = 0;
543                for (int iZone = 0 ; iZone < nbZones - 1 ; iZone++) {
544                    gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];
545                    const int upperLimit =
546                        (customsplits) ?
547                            (d->DimensionUpperLimits[dim]) ?
548                                d->DimensionUpperLimits[dim] : d->VelocityUpperLimit
549                            : (iZone+1) * (int)region->pDimensionDefinitions[dim].zone_size - 1;
550                    int limit = upperLimit + 1;
551                    int limitx = int((w - label_width - 1) * limit / 128.0 + 0.5) + label_width;
552                    if (x <= limitx - 2) break;
553                    if (x <= limitx + 2) {
554                        resize.dimension = dim;
555                        resize.offset = iZone << bitpos;
556                        resize.pos = limit;
557                        resize.min = prev_limit;
558    
559                        int dr = (dimregno >> bitpos) &
560                            ((1 << region->pDimensionDefinitions[dim].bits) - 1);
561                        resize.selected = dr == iZone ? resize.left :
562                            dr == iZone + 1 ? resize.right : resize.none;
563    
564                        iZone++;
565                        gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];
566    
567                        const int upperLimit =
568                            (customsplits) ?
569                                (d->DimensionUpperLimits[dim]) ?
570                                    d->DimensionUpperLimits[dim] : d->VelocityUpperLimit
571                                : (iZone+1) * (int)region->pDimensionDefinitions[dim].zone_size - 1;
572    
573                        int limit = upperLimit + 1;
574                        resize.max = limit;
575                        return true;
576                    }
577                    prev_limit = limit;
578                }
579            }
580        }
581        return false;
582    }
583    
584  sigc::signal<void> DimRegionChooser::signal_sel_changed()  sigc::signal<void> DimRegionChooser::signal_sel_changed()
585  {  {
586      return sel_changed_signal;      return sel_changed_signal;

Legend:
Removed from v.1052  
changed lines
  Added in v.1197

  ViewVC Help
Powered by ViewVC