/[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 1656 by schoenebeck, Sat Feb 2 08:18:19 2008 UTC revision 2246 by persson, Fri Aug 19 10:55:41 2011 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2008 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      set_flags(Gtk::CAN_FOCUS);      set_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    #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    
 bool DimRegionChooser::on_expose_event(GdkEventExpose* event)  
 {  
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      int w = get_width();      int w = get_width();
     Glib::RefPtr<Gdk::Window> window = get_window();  
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="keyswitching"; 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              // draw dimension's zone borders                                (w - label_width - 2), h - 2);
206              if (customsplits) {                  cr->fill();
207                  window->draw_line(black, label_width, y + 1, label_width, y + h - 2);  
208                  for (int j = 0 ; j < nbZones ; j++) {                  int c = 0;
209                      gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];                  if (dimregno >= 0) {
210                      int upperLimit = d->DimensionUpperLimits[i];                      int mask =
211                      if (!upperLimit) upperLimit = d->VelocityUpperLimit;                          ~(((1 << region->pDimensionDefinitions[i].bits) - 1) <<
212                      int v = upperLimit + 1;                            bitpos);
213                      int x = int((w - label_width - 1) * v / 128.0 + 0.5);                      c = dimregno & mask; // mask away this dimension
214                      window->draw_line(black, label_width + x, y + 1, label_width + x, y + h - 2);                  }
215                  }                  bool customsplits =
216              } else {                      ((region->pDimensionDefinitions[i].split_type ==
217                  for (int j = 0 ; j <= nbZones ; j++) {                        gig::split_type_normal &&
218                      int x = int((w - label_width - 1) * j / double(nbZones) + 0.5);                        region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||
219                      window->draw_line(black, label_width + x, y + 1, label_width + x, y + h - 2);                       (region->pDimensionDefinitions[i].dimension ==
220                  }                        gig::dimension_velocity &&
221              }                        region->pDimensionRegions[c]->VelocityUpperLimit));
222    
223              // draw fill for currently selected zone                  // draw dimension's zone borders
224              if (dimregno >= 0) {                  Gdk::Cairo::set_source_rgba(cr, black);
                 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                        if (customsplits) {
260                            int x1 = label_width;
261                            for (int j = 0 ; j < nbZones && x1 + 1 < clipx2 ; j++) {
262                                gig::DimensionRegion* d =
263                                    region->pDimensionRegions[c + (j << bitpos)];
264                                int upperLimit = d->DimensionUpperLimits[i];
265                                if (!upperLimit) {
266                                    upperLimit = d->VelocityUpperLimit;
267                                }
268                                int v = upperLimit + 1;
269                                int x2 = int((w - label_width - 1) * v / 128.0 +
270                                             0.5) + label_width;
271                                if (j == dr && x1 < x2) {
272                                    cr->rectangle(x1 + 1, y + 1,
273                                                  (x2 - x1) - 1, h - 2);
274                                    cr->fill();
275                                    break;
276                                }
277                                x1 = x2;
278                            }
279                        } else {
280                            if (dr < nbZones) {
281                                int x1 = int((w - label_width - 1) * dr /
282                                             double(nbZones) + 0.5);
283                                int x2 = int((w - label_width - 1) * (dr + 1) /
284                                             double(nbZones) + 0.5);
285                                cr->rectangle(label_width + x1 + 1, y + 1,
286                                              (x2 - x1) - 1, h - 2);
287                                cr->fill();
288                            }
289                      }                      }
290                  }                  }
291              }              }
# Line 228  bool DimRegionChooser::on_expose_event(G Line 298  bool DimRegionChooser::on_expose_event(G
298      return true;      return true;
299  }  }
300    
 void DimRegionChooser::on_size_request(GtkRequisition* requisition)  
 {  
     *requisition = GtkRequisition();  
     requisition->height = region ? nbDimensions * 20 : 0;  
     requisition->width = 800;  
 }  
   
301  void DimRegionChooser::set_region(gig::Region* region)  void DimRegionChooser::set_region(gig::Region* region)
302  {  {
303      this->region = region;      this->region = region;
# Line 256  void DimRegionChooser::set_region(gig::R Line 319  void DimRegionChooser::set_region(gig::R
319          dimreg = 0;          dimreg = 0;
320      }      }
321      dimregion_selected();      dimregion_selected();
322        set_size_request(800, region ? nbDimensions * 20 : 0);
323    
324        labels_changed = true;
325      queue_resize();      queue_resize();
326  }  }
327    
# Line 282  void DimRegionChooser::get_dimregions(co Line 348  void DimRegionChooser::get_dimregions(co
348      if (stereo_bit) dimregs.insert(region->pDimensionRegions[dimregno | stereo_bit]);      if (stereo_bit) dimregs.insert(region->pDimensionRegions[dimregno | stereo_bit]);
349  }  }
350    
351    void DimRegionChooser::update_after_resize()
 bool DimRegionChooser::on_button_release_event(GdkEventButton* event)  
352  {  {
353      if (resize.active) {      if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
         get_window()->pointer_ungrab(event->time);  
         resize.active = false;  
   
         if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {  
354    
355              int bitpos = 0;          int bitpos = 0;
356              for (int j = 0 ; j < resize.dimension ; j++) {          for (int j = 0 ; j < resize.dimension ; j++) {
357                  bitpos += region->pDimensionDefinitions[j].bits;              bitpos += region->pDimensionDefinitions[j].bits;
358            }
359            int mask =
360                ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
361            int c = dimregno & mask; // mask away this dimension
362    
363            if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {
364                // the velocity dimension didn't previously have
365                // custom v3 splits, so we initialize all splits with
366                // default values
367                int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
368                for (int j = 0 ; j < nbZones ; j++) {
369                    gig::DimensionRegion* d = region->pDimensionRegions[c + (j << bitpos)];
370                    d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
371                }
372            }
373            if (region->pDimensionRegions[c]->VelocityUpperLimit == 0) {
374                // the velocity dimension didn't previously have
375                // custom v2 splits, so we initialize all splits with
376                // default values
377                int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
378                for (int j = 0 ; j < nbZones ; j++) {
379                    gig::DimensionRegion* d = region->pDimensionRegions[c + (j << bitpos)];
380                    d->VelocityUpperLimit = int(128.0 * (j + 1) / nbZones - 1);
381              }              }
382              int mask =          }
                 ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);  
             int c = dimregno & mask; // mask away this dimension  
383    
384              if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {          gig::DimensionRegion* d = region->pDimensionRegions[c + resize.offset];
385                  // the velocity dimension didn't previously have          // update both v2 and v3 values
386                  // custom v3 splits, so we initialize all splits with          d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
387                  // default values          d->VelocityUpperLimit = resize.pos - 1;
388                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;  
389                  for (int j = 0 ; j < nbZones ; j++) {      } else {
390                      gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];          for (int i = 0 ; i < region->DimensionRegions ; ) {
391                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);  
392                if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {
393                    // the dimension didn't previously have custom
394                    // limits, so we have to set default limits for
395                    // all the dimension regions
396                    int bitpos = 0;
397                    for (int j = 0 ; j < resize.dimension ; j++) {
398                        bitpos += region->pDimensionDefinitions[j].bits;
399                  }                  }
             }  
             if (region->pDimensionRegions[c]->VelocityUpperLimit == 0) {  
                 // the velocity dimension didn't previously have  
                 // custom v2 splits, so we initialize all splits with  
                 // default values  
400                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
401    
402                  for (int j = 0 ; j < nbZones ; j++) {                  for (int j = 0 ; j < nbZones ; j++) {
403                      gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];                      gig::DimensionRegion* d = region->pDimensionRegions[i + (j << bitpos)];
404                      d->VelocityUpperLimit = int(128.0 * (j + 1) / nbZones - 1);                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
405                  }                  }
406              }              }
407                gig::DimensionRegion* d = region->pDimensionRegions[i + resize.offset];
             gig::DimensionRegion *d = region->pDimensionRegions[c + resize.offset];  
             // update both v2 and v3 values  
408              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 ; ) {  
409    
410                  if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {              int bitpos = 0;
411                      // the dimension didn't previously have custom              int j;
412                      // limits, so we have to set default limits for              for (j = 0 ; j < region->Dimensions ; j++) {
413                      // all the dimension regions                  if (j != resize.dimension) {
414                      int bitpos = 0;                      int maxzones = 1 << region->pDimensionDefinitions[j].bits;
415                      for (int j = 0 ; j < resize.dimension ; j++) {                      int dimj = (i >> bitpos) & (maxzones - 1);
416                          bitpos += region->pDimensionDefinitions[j].bits;                      if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;
                     }  
                     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;  
   
                 int bitpos = 0;  
                 int j;  
                 for (j = 0 ; j < region->Dimensions ; j++) {  
                     if (j != resize.dimension) {  
                         int maxzones = 1 << region->pDimensionDefinitions[j].bits;  
                         int dimj = (i >> bitpos) & (maxzones - 1);  
                         if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;  
                     }  
                     bitpos += region->pDimensionDefinitions[j].bits;  
417                  }                  }
418                  if (j == region->Dimensions) break;                  bitpos += region->pDimensionDefinitions[j].bits;
                 i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);  
419              }              }
420                if (j == region->Dimensions) break;
421                i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
422          }          }
423        }
424    }
425    
426    bool DimRegionChooser::on_button_release_event(GdkEventButton* event)
427    {
428        if (resize.active) {
429    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
430            get_window()->pointer_ungrab(event->time);
431    #else
432            Glib::wrap(event->device, true)->ungrab(event->time);
433    #endif
434            resize.active = false;
435    
436          region_changed();          region_changed();
437    
438          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 377  bool DimRegionChooser::on_button_press_e Line 450  bool DimRegionChooser::on_button_press_e
450          event->x >= label_width && event->x < w) {          event->x >= label_width && event->x < w) {
451    
452          if (is_in_resize_zone(event->x, event->y)) {          if (is_in_resize_zone(event->x, event->y)) {
453              Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
454              get_window()->pointer_grab(false,              get_window()->pointer_grab(false,
455                                         Gdk::BUTTON_RELEASE_MASK |                                         Gdk::BUTTON_RELEASE_MASK |
456                                         Gdk::POINTER_MOTION_MASK |                                         Gdk::POINTER_MOTION_MASK |
457                                         Gdk::POINTER_MOTION_HINT_MASK,                                         Gdk::POINTER_MOTION_HINT_MASK,
458                                         double_arrow, event->time);                                         Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW),
459                                           event->time);
460    #else
461                Glib::wrap(event->device, true)->grab(get_window(),
462                                                      Gdk::OWNERSHIP_NONE,
463                                                      false,
464                                                      Gdk::BUTTON_RELEASE_MASK |
465                                                      Gdk::POINTER_MOTION_MASK |
466                                                      Gdk::POINTER_MOTION_HINT_MASK,
467                                                      Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW),
468                                                      event->time);
469    #endif
470              resize.active = true;              resize.active = true;
471          } else {          } else {
472              int ydim = int(event->y / h);              int ydim = int(event->y / h);
# Line 415  bool DimRegionChooser::on_button_press_e Line 499  bool DimRegionChooser::on_button_press_e
499    
500                  if (region->pDimensionRegions[c]->DimensionUpperLimits[i]) {                  if (region->pDimensionRegions[c]->DimensionUpperLimits[i]) {
501                      for (z = 0 ; z < nbZones ; z++) {                      for (z = 0 ; z < nbZones ; z++) {
502                          gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];                          gig::DimensionRegion* d = region->pDimensionRegions[c + (z << bitpos)];
503                          if (val <= d->DimensionUpperLimits[i]) break;                          if (val <= d->DimensionUpperLimits[i]) break;
504                      }                      }
505                  } else {                  } else {
506                      for (z = 0 ; z < nbZones ; z++) {                      for (z = 0 ; z < nbZones ; z++) {
507                          gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];                          gig::DimensionRegion* d = region->pDimensionRegions[c + (z << bitpos)];
508                          if (val <= d->VelocityUpperLimit) break;                          if (val <= d->VelocityUpperLimit) break;
509                      }                      }
510                  }                  }
# Line 464  bool DimRegionChooser::on_motion_notify_ Line 548  bool DimRegionChooser::on_motion_notify_
548          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
549    
550          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();  
   
551              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;
552              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;
553              int y = resize.dimension * h;              int y = resize.dimension * h;
554                int x1, x2;
555              if (resize.selected == resize.none) {              if (k > resize.pos) {
556                  if (resize.pos != resize.min && resize.pos != resize.max) {                  x1 = prevx;
557                      window->draw_line(white, prevx, y + 1, prevx, y + h - 2);                  x2 = x;
                 }  
558              } else {              } else {
559                  gc->set_foreground(red);                  x1 = x;
560                    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);  
                 }  
561              }              }
562              window->draw_line(black, x, y + 1, x, y + h - 2);              Gdk::Rectangle rect(x1, y + 1, x2 - x1 + 1, h - 2);
563    
564              resize.pos = k;              resize.pos = k;
565                update_after_resize();
566                get_window()->invalidate_rect(rect, false);
567          }          }
568      } else {      } else {
569          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
570              if (!cursor_is_resize) {              if (!cursor_is_resize) {
571                  Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
572                  window->set_cursor(double_arrow);                  window->set_cursor(Gdk::Cursor(Gdk::SB_H_DOUBLE_ARROW));
573    #else
574                    window->set_cursor(Gdk::Cursor::create(Gdk::SB_H_DOUBLE_ARROW));
575    #endif
576                  cursor_is_resize = true;                  cursor_is_resize = true;
577              }              }
578          } else if (cursor_is_resize) {          } else if (cursor_is_resize) {
# Line 546  bool DimRegionChooser::is_in_resize_zone Line 613  bool DimRegionChooser::is_in_resize_zone
613          if (region->pDimensionDefinitions[dim].split_type != gig::split_type_bit) {          if (region->pDimensionDefinitions[dim].split_type != gig::split_type_bit) {
614              int prev_limit = 0;              int prev_limit = 0;
615              for (int iZone = 0 ; iZone < nbZones - 1 ; iZone++) {              for (int iZone = 0 ; iZone < nbZones - 1 ; iZone++) {
616                  gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];                  gig::DimensionRegion* d = region->pDimensionRegions[c + (iZone << bitpos)];
617                  const int upperLimit =                  const int upperLimit =
618                      (customsplits) ?                      (customsplits) ?
619                          (d->DimensionUpperLimits[dim]) ?                          (d->DimensionUpperLimits[dim]) ?
# Line 567  bool DimRegionChooser::is_in_resize_zone Line 634  bool DimRegionChooser::is_in_resize_zone
634                          dr == iZone + 1 ? resize.right : resize.none;                          dr == iZone + 1 ? resize.right : resize.none;
635    
636                      iZone++;                      iZone++;
637                      gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];                      gig::DimensionRegion* d = region->pDimensionRegions[c + (iZone << bitpos)];
638    
639                      const int upperLimit =                      const int upperLimit =
640                          (customsplits) ?                          (customsplits) ?

Legend:
Removed from v.1656  
changed lines
  Added in v.2246

  ViewVC Help
Powered by ViewVC