/[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 2626 by schoenebeck, Thu Jun 12 15:12:00 2014 UTC revision 3147 by schoenebeck, Wed May 3 21:23:16 2017 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2014 Andreas Persson   * Copyright (C) 2006-2017 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 17  Line 17 
17   * 02110-1301 USA.   * 02110-1301 USA.
18   */   */
19    
20    #include <gtkmm/box.h>
21  #include "dimregionchooser.h"  #include "dimregionchooser.h"
22  #include <cairomm/context.h>  #include <cairomm/context.h>
23    #include <cairomm/surface.h>
24  #include <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
25  #include <gdkmm/general.h>  #include <gdkmm/general.h>
26  #include <glibmm/stringutils.h>  #include <glibmm/stringutils.h>
 #include <gtkmm/stock.h>  
27  #include <glibmm/ustring.h>  #include <glibmm/ustring.h>
28  #include <gtkmm/messagedialog.h>  #include <gtkmm/messagedialog.h>
29    #include <assert.h>
30    
31  #include "global.h"  #include "global.h"
32    #include "gfx/builtinpix.h"
33    
34  // taken from gdk/gdkkeysyms.h  //TODO: this function and dimensionCaseOf() from global.h are duplicates, eliminate either one of them!
35  // (define on demand, to avoid unnecessary dev lib package build dependency)  static DimensionCase caseOfDimRegion(gig::DimensionRegion* dr, bool* isValidZone) {
36  #ifndef GDK_KEY_Control_L      DimensionCase dimCase;
 # define GDK_KEY_Control_L 0xffe3  
 #endif  
 #ifndef GDK_KEY_Control_R  
 # define GDK_KEY_Control_R 0xffe4  
 #endif  
   
 static std::map<gig::dimension_t,int> caseOfDimRegion(gig::DimensionRegion* dr, bool* isValidZone) {  
     std::map<gig::dimension_t,int> dimCase;  
37      if (!dr) {      if (!dr) {
38          *isValidZone = false;          *isValidZone = false;
39          return dimCase;          return dimCase;
# Line 56  static std::map<gig::dimension_t,int> ca Line 51  static std::map<gig::dimension_t,int> ca
51      if (drIndex == 256) {      if (drIndex == 256) {
52          fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");          fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");
53          *isValidZone = false;          *isValidZone = false;
54          return std::map<gig::dimension_t,int>();          return DimensionCase();
55      }      }
56    
57      for (int d = 0, baseBits = 0; d < rgn->Dimensions; ++d) {      for (int d = 0, baseBits = 0; d < rgn->Dimensions; ++d) {
# Line 67  static std::map<gig::dimension_t,int> ca Line 62  static std::map<gig::dimension_t,int> ca
62          // there are also DimensionRegion objects of unused zones, skip them          // there are also DimensionRegion objects of unused zones, skip them
63          if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {          if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {
64              *isValidZone = false;              *isValidZone = false;
65              return std::map<gig::dimension_t,int>();              return DimensionCase();
66          }          }
67      }      }
68    
# Line 76  static std::map<gig::dimension_t,int> ca Line 71  static std::map<gig::dimension_t,int> ca
71  }  }
72    
73  DimRegionChooser::DimRegionChooser(Gtk::Window& window) :  DimRegionChooser::DimRegionChooser(Gtk::Window& window) :
74      red("#8070ff"),      red("#ff476e"),
75        blue("#4796ff"),
76      black("black"),      black("black"),
77      white("white")      white("white")
78  {  {
79        // make sure blue hatched pattern pixmap is loaded
80        loadBuiltInPix();
81    
82        // create blue hatched pattern
83        {
84            const int width = blueHatchedPattern->get_width();
85            const int height = blueHatchedPattern->get_height();
86            const int stride = blueHatchedPattern->get_rowstride();
87    
88            // manually convert from RGBA to ARGB
89            this->blueHatchedPatternARGB = blueHatchedPattern->copy();
90            const int pixelSize = stride / width;
91            const int totalPixels = width * height;
92            assert(pixelSize == 4);
93            unsigned char* ptr = this->blueHatchedPatternARGB->get_pixels();
94            for (int iPixel = 0; iPixel < totalPixels; ++iPixel, ptr += pixelSize) {
95                const unsigned char r = ptr[0];
96                const unsigned char g = ptr[1];
97                const unsigned char b = ptr[2];
98                const unsigned char a = ptr[3];
99                ptr[0] = b;
100                ptr[1] = g;
101                ptr[2] = r;
102                ptr[3] = a;
103            }
104    
105            Cairo::RefPtr<Cairo::ImageSurface> imageSurface = Cairo::ImageSurface::create(
106                this->blueHatchedPatternARGB->get_pixels(), Cairo::FORMAT_ARGB32, width, height, stride
107            );
108            this->blueHatchedSurfacePattern = Cairo::SurfacePattern::create(imageSurface);
109            this->blueHatchedSurfacePattern->set_extend(Cairo::EXTEND_REPEAT);
110        }
111    
112        // create gray blue hatched pattern
113        {
114            const int width = grayBlueHatchedPattern->get_width();
115            const int height = grayBlueHatchedPattern->get_height();
116            const int stride = grayBlueHatchedPattern->get_rowstride();
117    
118            // manually convert from RGBA to ARGB
119            this->grayBlueHatchedPatternARGB = grayBlueHatchedPattern->copy();
120            const int pixelSize = stride / width;
121            const int totalPixels = width * height;
122            assert(pixelSize == 4);
123            unsigned char* ptr = this->grayBlueHatchedPatternARGB->get_pixels();
124            for (int iPixel = 0; iPixel < totalPixels; ++iPixel, ptr += pixelSize) {
125                const unsigned char r = ptr[0];
126                const unsigned char g = ptr[1];
127                const unsigned char b = ptr[2];
128                const unsigned char a = ptr[3];
129                ptr[0] = b;
130                ptr[1] = g;
131                ptr[2] = r;
132                ptr[3] = a;
133            }
134    
135            Cairo::RefPtr<Cairo::ImageSurface> imageSurface = Cairo::ImageSurface::create(
136                this->grayBlueHatchedPatternARGB->get_pixels(), Cairo::FORMAT_ARGB32, width, height, stride
137            );
138            this->grayBlueHatchedSurfacePattern = Cairo::SurfacePattern::create(imageSurface);
139            this->grayBlueHatchedSurfacePattern->set_extend(Cairo::EXTEND_REPEAT);
140        }
141    
142      instrument = 0;      instrument = 0;
143      region = 0;      region = 0;
144      maindimregno = -1;      maindimregno = -1;
145        maindimtype = gig::dimension_none; // initialize with invalid dimension type
146      focus_line = 0;      focus_line = 0;
147      resize.active = false;      resize.active = false;
148      cursor_is_resize = false;      cursor_is_resize = false;
149      h = 20;      h = 24;
150      multiSelectKeyDown = false;      multiSelectKeyDown = false;
151        primaryKeyDown = false;
152        shiftKeyDown = false;
153        modifybothchannels = modifyalldimregs = modifybothchannels = false;
154      set_can_focus();      set_can_focus();
155    
156        const Glib::ustring txtUseCheckBoxAllRegions =
157            _("Use checkbox 'all regions' to control whether this should apply to all regions.");
158    
159      actionGroup = Gtk::ActionGroup::create();      actionGroup = Gtk::ActionGroup::create();
160        actionSplitDimZone = Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone"), txtUseCheckBoxAllRegions);
161        actionSplitDimZone->set_tooltip(txtUseCheckBoxAllRegions); //FIXME: doesn't work? why???
162      actionGroup->add(      actionGroup->add(
163          Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone")),          actionSplitDimZone,
164          sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)          sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)
165      );      );
166        actionDeleteDimZone = Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone"), txtUseCheckBoxAllRegions);
167        actionDeleteDimZone->set_tooltip(txtUseCheckBoxAllRegions); //FIXME: doesn't work? why???
168      actionGroup->add(      actionGroup->add(
169          Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone")),          actionDeleteDimZone,
170          sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)          sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)
171      );      );
172    
# Line 141  DimRegionChooser::~DimRegionChooser() Line 211  DimRegionChooser::~DimRegionChooser()
211  {  {
212  }  }
213    
214    void DimRegionChooser::setModifyBothChannels(bool b) {
215        modifybothchannels = b;
216        // redraw required parts
217        queue_draw();
218    }
219    
220    void DimRegionChooser::setModifyAllDimensionRegions(bool b) {
221        modifyalldimregs = b;
222        // redraw required parts
223        queue_draw();
224    }
225    
226    void DimRegionChooser::setModifyAllRegions(bool b) {
227        modifyallregions = b;
228    
229        actionDeleteDimZone->set_label(b ? _("Delete Dimension Zone [ALL REGIONS]") : _("Delete Dimension Zone"));
230        actionSplitDimZone->set_label(b ? _("Split Dimensions Zone [ALL REGIONS]") : _("Split Dimensions Zone"));
231    
232        // redraw required parts
233        queue_draw();
234    }
235    
236  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
237  bool DimRegionChooser::on_expose_event(GdkEventExpose* e)  bool DimRegionChooser::on_expose_event(GdkEventExpose* e)
238  {  {
# Line 229  bool DimRegionChooser::on_draw(const Cai Line 321  bool DimRegionChooser::on_draw(const Cai
321                      dstr = dstrbuf;                      dstr = dstrbuf;
322                      break;                      break;
323                  }                  }
                 layout->set_text(dstr);  
324    
325                    // Since bold font yields in larger label width, we first always
326                    // set the bold text variant, retrieve its dimensions (as worst
327                    // case dimensions of the label) ...
328                    layout->set_markup("<b>" + Glib::ustring(dstr) + "</b>");
329                  Pango::Rectangle rectangle = layout->get_logical_extents();                  Pango::Rectangle rectangle = layout->get_logical_extents();
330                    // ... and then reset the label to regular font style in case
331                    // the line is not selected. Otherwise the right hand side
332                    // actual dimension zones would jump around on selection change.
333                    bool isSelectedLine = (focus_line == i);
334                    if (!isSelectedLine)
335                        layout->set_markup(dstr);
336    
337                  double text_w = double(rectangle.get_width()) / Pango::SCALE;                  double text_w = double(rectangle.get_width()) / Pango::SCALE;
338                  if (text_w > maxwidth) maxwidth = text_w;                  if (text_w > maxwidth) maxwidth = text_w;
339    
# Line 273  bool DimRegionChooser::on_draw(const Cai Line 375  bool DimRegionChooser::on_draw(const Cai
375                  // draw focus rectangle around dimension's label and zones                  // draw focus rectangle around dimension's label and zones
376                  if (has_focus() && focus_line == i) {                  if (has_focus() && focus_line == i) {
377  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
378                      Gdk::Rectangle farea(0, y, 150, 20);                      Gdk::Rectangle farea(0, y, 150, h);
379                      get_style()->paint_focus(get_window(), get_state(), farea,                      get_style()->paint_focus(get_window(), get_state(), farea,
380                                               *this, "",                                               *this, "",
381                                               0, y, label_width, 20);                                               0, y, label_width, h);
382  #else  #else
383                      get_style_context()->render_focus(cr,                      get_style_context()->render_focus(cr,
384                                                        0, y, label_width, 20);                                                        0, y, label_width, h);
385  #endif  #endif
386                  }                  }
387    
# Line 318  bool DimRegionChooser::on_draw(const Cai Line 420  bool DimRegionChooser::on_draw(const Cai
420                      cr->move_to(label_width + 0.5, y + 1);                      cr->move_to(label_width + 0.5, y + 1);
421                      cr->line_to(label_width + 0.5, y + h - 1);                      cr->line_to(label_width + 0.5, y + h - 1);
422                      int prevX = label_width;                      int prevX = label_width;
423                      int prevUpperLimit = 0;                      int prevUpperLimit = -1;
424    
425                      for (int j = 0 ; j < nbZones ; j++) {                      for (int j = 0 ; j < nbZones ; j++) {
426                          // draw dimension zone's borders for custom splits                          // draw dimension zone's borders for custom splits
# Line 338  bool DimRegionChooser::on_draw(const Cai Line 440  bool DimRegionChooser::on_draw(const Cai
440    
441                          // draw fill for zone                          // draw fill for zone
442                          bool isSelectedZone = this->dimzones[dimension].count(j);                          bool isSelectedZone = this->dimzones[dimension].count(j);
443                          Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);                          bool isMainSelection =
444                                this->maindimcase.find(dimension) != this->maindimcase.end() &&
445                                this->maindimcase[dimension] == j;
446                            bool isCheckBoxSelected =
447                                modifyalldimregs ||
448                                (modifybothchannels &&
449                                    dimension == gig::dimension_samplechannel);
450                            if (isMainSelection)
451                                Gdk::Cairo::set_source_rgba(cr, blue);
452                            else if (isSelectedZone)
453                                cr->set_source(blueHatchedSurfacePattern);
454                            else if (isCheckBoxSelected)
455                                cr->set_source(grayBlueHatchedSurfacePattern);
456                            else
457                                Gdk::Cairo::set_source_rgba(cr, white);
458    
459                          cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);                          cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
460                          cr->fill();                          cr->fill();
461    
# Line 346  bool DimRegionChooser::on_draw(const Cai Line 463  bool DimRegionChooser::on_draw(const Cai
463                          // as numeric value to the user                          // as numeric value to the user
464                          {                          {
465                              Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                              Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
466                              layout->set_text(Glib::Ascii::dtostr(prevUpperLimit));                              layout->set_text(Glib::Ascii::dtostr(prevUpperLimit+1));
467                              Gdk::Cairo::set_source_rgba(cr, black);                              Gdk::Cairo::set_source_rgba(cr, black);
                             Pango::Rectangle rect = layout->get_logical_extents();  
468                              // get the text dimensions                              // get the text dimensions
469                              int text_width, text_height;                              int text_width, text_height;
470                              layout->get_pixel_size(text_width, text_height);                              layout->get_pixel_size(text_width, text_height);
471                              // move text to the left end of the dimension zone                              // move text to the left end of the dimension zone
472                              cr->move_to(prevX + 3, y + 1);                              cr->move_to(prevX + 3, y + (h - text_height) / 2);
473  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
474                              pango_cairo_show_layout(cr->cobj(), layout->gobj());                              pango_cairo_show_layout(cr->cobj(), layout->gobj());
475  #else  #else
# Line 366  bool DimRegionChooser::on_draw(const Cai Line 482  bool DimRegionChooser::on_draw(const Cai
482                              Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                              Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
483                              layout->set_text(Glib::Ascii::dtostr(upperLimit));                              layout->set_text(Glib::Ascii::dtostr(upperLimit));
484                              Gdk::Cairo::set_source_rgba(cr, black);                              Gdk::Cairo::set_source_rgba(cr, black);
                             Pango::Rectangle rect = layout->get_logical_extents();  
485                              // get the text dimensions                              // get the text dimensions
486                              int text_width, text_height;                              int text_width, text_height;
487                              layout->get_pixel_size(text_width, text_height);                              layout->get_pixel_size(text_width, text_height);
488                              // move text to the left end of the dimension zone                              // move text to the left end of the dimension zone
489                              cr->move_to(x - 3 - text_width, y + 1);                              cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
490  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
491                              pango_cairo_show_layout(cr->cobj(), layout->gobj());                              pango_cairo_show_layout(cr->cobj(), layout->gobj());
492  #else  #else
# Line 398  bool DimRegionChooser::on_draw(const Cai Line 513  bool DimRegionChooser::on_draw(const Cai
513                          if (j != 0) {                          if (j != 0) {
514                              // draw fill for zone                              // draw fill for zone
515                              bool isSelectedZone = this->dimzones[dimension].count(j-1);                              bool isSelectedZone = this->dimzones[dimension].count(j-1);
516                              Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);                              bool isMainSelection =
517                                    this->maindimcase.find(dimension) != this->maindimcase.end() &&
518                                    this->maindimcase[dimension] == (j-1);
519                                bool isCheckBoxSelected =
520                                    modifyalldimregs ||
521                                    (modifybothchannels &&
522                                        dimension == gig::dimension_samplechannel);
523                                if (isMainSelection)
524                                    Gdk::Cairo::set_source_rgba(cr, blue);
525                                else if (isSelectedZone)
526                                    cr->set_source(blueHatchedSurfacePattern);
527                                else if (isCheckBoxSelected)
528                                    cr->set_source(grayBlueHatchedSurfacePattern);
529                                else
530                                    Gdk::Cairo::set_source_rgba(cr, white);
531                              cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);                              cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
532                              cr->fill();                              cr->fill();
533    
# Line 408  bool DimRegionChooser::on_draw(const Cai Line 537  bool DimRegionChooser::on_draw(const Cai
537                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
538                                  layout->set_text(Glib::Ascii::dtostr((j-1) * 128/nbZones));                                  layout->set_text(Glib::Ascii::dtostr((j-1) * 128/nbZones));
539                                  Gdk::Cairo::set_source_rgba(cr, black);                                  Gdk::Cairo::set_source_rgba(cr, black);
                                 Pango::Rectangle rect = layout->get_logical_extents();  
540                                  // get the text dimensions                                  // get the text dimensions
541                                  int text_width, text_height;                                  int text_width, text_height;
542                                  layout->get_pixel_size(text_width, text_height);                                  layout->get_pixel_size(text_width, text_height);
543                                  // move text to the left end of the dimension zone                                  // move text to the left end of the dimension zone
544                                  cr->move_to(prevX + 3, y + 1);                                  cr->move_to(prevX + 3, y + (h - text_height) / 2);
545  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
546                                  pango_cairo_show_layout(cr->cobj(), layout->gobj());                                  pango_cairo_show_layout(cr->cobj(), layout->gobj());
547  #else  #else
# Line 426  bool DimRegionChooser::on_draw(const Cai Line 554  bool DimRegionChooser::on_draw(const Cai
554                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
555                                  layout->set_text(Glib::Ascii::dtostr(j * 128/nbZones - 1));                                  layout->set_text(Glib::Ascii::dtostr(j * 128/nbZones - 1));
556                                  Gdk::Cairo::set_source_rgba(cr, black);                                  Gdk::Cairo::set_source_rgba(cr, black);
                                 Pango::Rectangle rect = layout->get_logical_extents();  
557                                  // get the text dimensions                                  // get the text dimensions
558                                  int text_width, text_height;                                  int text_width, text_height;
559                                  layout->get_pixel_size(text_width, text_height);                                  layout->get_pixel_size(text_width, text_height);
560                                  // move text to the left end of the dimension zone                                  // move text to the left end of the dimension zone
561                                  cr->move_to(x - 3 - text_width, y + 1);                                  cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
562  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
563                                  pango_cairo_show_layout(cr->cobj(), layout->gobj());                                  pango_cairo_show_layout(cr->cobj(), layout->gobj());
564  #else  #else
# Line 469  void DimRegionChooser::set_region(gig::R Line 596  void DimRegionChooser::set_region(gig::R
596          }          }
597      }      }
598      dimregion_selected();      dimregion_selected();
599      set_size_request(800, region ? nbDimensions * 20 : 0);      set_size_request(800, region ? nbDimensions * h : 0);
600    
601      labels_changed = true;      labels_changed = true;
602      queue_resize();      queue_resize();
# Line 511  void DimRegionChooser::get_dimregions(co Line 638  void DimRegionChooser::get_dimregions(co
638    
639  void DimRegionChooser::update_after_resize()  void DimRegionChooser::update_after_resize()
640  {  {
641      if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {      const uint8_t upperLimit = resize.pos - 1;
642        gig::Instrument* instr = (gig::Instrument*)region->GetParent();
643    
644          int bitpos = 0;      int bitpos = 0;
645          for (int j = 0 ; j < resize.dimension ; j++) {      for (int j = 0 ; j < resize.dimension ; j++) {
646              bitpos += region->pDimensionDefinitions[j].bits;          bitpos += region->pDimensionDefinitions[j].bits;
647          }      }
648    
649        const int stereobitpos =
650            (modifybothchannels) ? baseBits(gig::dimension_samplechannel, region) : -1;
651    
652        // the velocity dimension must be handled differently than all other
653        // dimension types, because
654        // 1. it is currently the only dimension type which allows different zone
655        //    sizes for different cases
656        // 2. for v2 format VelocityUpperLimit has to be set, DimensionUpperLimits for v3
657        if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
658          int mask =          int mask =
659              ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);              ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
660          int c = maindimregno & mask; // mask away this dimension          int c = maindimregno & mask; // mask away this dimension
# Line 542  void DimRegionChooser::update_after_resi Line 680  void DimRegionChooser::update_after_resi
680              }              }
681          }          }
682    
683          gig::DimensionRegion* d = region->pDimensionRegions[c + resize.offset];          int index = c + (resize.zone << bitpos);
684            gig::DimensionRegion* d = region->pDimensionRegions[index];
685          // update both v2 and v3 values          // update both v2 and v3 values
686          d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;          d->DimensionUpperLimits[resize.dimension] = upperLimit;
687          d->VelocityUpperLimit = resize.pos - 1;          d->VelocityUpperLimit = upperLimit;
688            if (modifybothchannels && stereobitpos >= 0) { // do the same for the other audio channel's dimregion ...
689                gig::DimensionRegion* d = region->pDimensionRegions[index ^ (1 << stereobitpos)];
690                d->DimensionUpperLimits[resize.dimension] = upperLimit;
691                d->VelocityUpperLimit = upperLimit;
692            }
693    
694            if (modifyalldimregs) {
695                gig::Region* rgn = NULL;
696                for (int key = 0; key < 128; ++key) {
697                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
698                    rgn = instr->GetRegion(key);
699                    if (!modifyallregions && rgn != region) continue; // hack to reduce overall code amount a bit
700                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
701                    if (!dimdef) continue;
702                    if (dimdef->zones != resize.dimensionDef.zones) continue;
703                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
704                    assert(iDim >= 0 && iDim < rgn->Dimensions);
705    
706                    // the dimension layout might be completely different in this
707                    // region, so we have to recalculate bitpos etc for this region
708                    const int bitpos = baseBits(resize.dimensionDef.dimension, rgn);
709                    const int stencil = ~(((1 << dimdef->bits) - 1) << bitpos);
710                    const int selection = resize.zone << bitpos;
711    
712                    // primitive and inefficient loop implementation, however due to
713                    // this circumstance the loop code is much simpler, and its lack
714                    // of runtime efficiency should not be notable in practice
715                    for (int idr = 0; idr < 256; ++idr) {
716                        const int index = (idr & stencil) | selection;
717                        assert(index >= 0 && index < 256);
718                        gig::DimensionRegion* dr = rgn->pDimensionRegions[index];
719                        if (!dr) continue;
720                        dr->DimensionUpperLimits[iDim] = upperLimit;
721                        d->VelocityUpperLimit = upperLimit;
722                    }
723                }
724            } else if (modifyallregions) { // implies modifyalldimregs is false ...
725                // resolve the precise case we need to modify for all other regions
726                DimensionCase dimCase = dimensionCaseOf(d);
727                // apply the velocity upper limit change to that resolved dim case
728                // of all regions ...
729                gig::Region* rgn = NULL;
730                for (int key = 0; key < 128; ++key) {
731                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
732                    rgn = instr->GetRegion(key);
733                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
734                    if (!dimdef) continue;
735                    if (dimdef->zones != resize.dimensionDef.zones) continue;
736                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
737                    assert(iDim >= 0 && iDim < rgn->Dimensions);
738    
739                    std::vector<gig::DimensionRegion*> dimrgns = dimensionRegionsMatching(dimCase, rgn);
740                    for (int i = 0; i < dimrgns.size(); ++i) {
741                        gig::DimensionRegion* dr = dimrgns[i];
742                        dr->DimensionUpperLimits[iDim] = upperLimit;
743                        dr->VelocityUpperLimit = upperLimit;
744                    }
745                }
746            }
747      } else {      } else {
748          for (int i = 0 ; i < region->DimensionRegions ; ) {          for (int i = 0 ; i < region->DimensionRegions ; ) {
   
749              if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {              if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {
750                  // the dimension didn't previously have custom                  // the dimension didn't previously have custom
751                  // limits, so we have to set default limits for                  // limits, so we have to set default limits for
752                  // all the dimension regions                  // all the dimension regions
                 int bitpos = 0;  
                 for (int j = 0 ; j < resize.dimension ; j++) {  
                     bitpos += region->pDimensionDefinitions[j].bits;  
                 }  
753                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
754    
755                  for (int j = 0 ; j < nbZones ; j++) {                  for (int j = 0 ; j < nbZones ; j++) {
# Line 565  void DimRegionChooser::update_after_resi Line 757  void DimRegionChooser::update_after_resi
757                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
758                  }                  }
759              }              }
760              gig::DimensionRegion* d = region->pDimensionRegions[i + resize.offset];              int index = i + (resize.zone << bitpos);
761              d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;              gig::DimensionRegion* d = region->pDimensionRegions[index];
762                d->DimensionUpperLimits[resize.dimension] = upperLimit;
763    #if 0       // the following is currently not necessary, because ATM the gig format uses for all dimension types except of the veleocity dimension the same zone sizes for all cases
764                if (modifybothchannels && stereobitpos >= 0) { // do the same for the other audio channel's dimregion ...
765                    gig::DimensionRegion* d = region->pDimensionRegions[index ^ (1 << stereobitpos)];
766                    d->DimensionUpperLimits[resize.dimension] = upperLimit;
767                }
768    #endif
769              int bitpos = 0;              int bitpos = 0;
770              int j;              int j;
771              for (j = 0 ; j < region->Dimensions ; j++) {              for (j = 0 ; j < region->Dimensions ; j++) {
# Line 581  void DimRegionChooser::update_after_resi Line 779  void DimRegionChooser::update_after_resi
779              if (j == region->Dimensions) break;              if (j == region->Dimensions) break;
780              i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);              i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
781          }          }
782    
783            if (modifyallregions) { // TODO: this code block could be merged with the similar (and more generalized) code block of the velocity dimension above
784                gig::Region* rgn = NULL;
785                for (int key = 0; key < 128; ++key) {
786                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
787                    rgn = instr->GetRegion(key);
788                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
789                    if (!dimdef) continue;
790                    if (dimdef->zones != resize.dimensionDef.zones) continue;
791                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
792                    assert(iDim >= 0 && iDim < rgn->Dimensions);
793    
794                    // the dimension layout might be completely different in this
795                    // region, so we have to recalculate bitpos etc for this region
796                    const int bitpos = baseBits(resize.dimensionDef.dimension, rgn);
797                    const int stencil = ~(((1 << dimdef->bits) - 1) << bitpos);
798                    const int selection = resize.zone << bitpos;
799    
800                    // this loop implementation is less efficient than the above's
801                    // loop implementation (which skips unnecessary dimension regions)
802                    // however this code is much simpler, and its lack of runtime
803                    // efficiency should not be notable in practice
804                    for (int idr = 0; idr < 256; ++idr) {
805                        const int index = (idr & stencil) | selection;
806                        assert(index >= 0 && index < 256);
807                        gig::DimensionRegion* dr = rgn->pDimensionRegions[index];
808                        if (!dr) continue;
809                        dr->DimensionUpperLimits[iDim] = upperLimit;
810                    }
811                }
812            }
813      }      }
814  }  }
815    
# Line 809  bool DimRegionChooser::is_in_resize_zone Line 1038  bool DimRegionChooser::is_in_resize_zone
1038                  if (x <= limitx - 2) break;                  if (x <= limitx - 2) break;
1039                  if (x <= limitx + 2) {                  if (x <= limitx + 2) {
1040                      resize.dimension = dim;                      resize.dimension = dim;
1041                      resize.offset = iZone << bitpos;                      resize.dimensionDef = region->pDimensionDefinitions[dim];
1042                        resize.zone = iZone;
1043                      resize.pos = limit;                      resize.pos = limit;
1044                      resize.min = prev_limit;                      resize.min = prev_limit;
1045    
# Line 850  sigc::signal<void>& DimRegionChooser::si Line 1080  sigc::signal<void>& DimRegionChooser::si
1080    
1081  bool DimRegionChooser::on_focus(Gtk::DirectionType direction)  bool DimRegionChooser::on_focus(Gtk::DirectionType direction)
1082  {  {
1083      // TODO: kolla att region finns osv, dvs att det går att sätta      // TODO: check that region exists etc, that is, that it's possible
1084      // fokus.      // to set focus
1085      if (direction == Gtk::DIR_TAB_FORWARD ||      if (direction == Gtk::DIR_TAB_FORWARD ||
1086          direction == Gtk::DIR_DOWN) {          direction == Gtk::DIR_DOWN) {
1087          if (!has_focus()) {          if (!has_focus()) {
# Line 883  bool DimRegionChooser::on_focus(Gtk::Dir Line 1113  bool DimRegionChooser::on_focus(Gtk::Dir
1113              }              }
1114          }          }
1115      } else if (!has_focus()) {      } else if (!has_focus()) {
1116          // TODO: kolla att focus_line finns!          // TODO: check that focus_line exists
1117          grab_focus();          grab_focus();
1118          return true;          return true;
1119      } else {      } else {
1120          // TODO: öka eller minska värde!          // TODO: increase or decrease value
1121      }      }
1122        return false;
1123  }  }
1124    
1125  void DimRegionChooser::split_dimension_zone() {      void DimRegionChooser::split_dimension_zone() {    
1126      printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);      printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1127      try {      try {
1128          region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);          if (!modifyallregions) {
1129                region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
1130            } else {
1131                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
1132                gig::dimension_def_t* pMaindimdef = region->GetDimensionDefinition(maindimtype);
1133                assert(pMaindimdef != NULL);
1134                // retain structure by value since the original region will be
1135                // modified in the loop below as well
1136                gig::dimension_def_t maindimdef = *pMaindimdef;
1137                std::vector<gig::Region*> ignoredAll;
1138                std::vector<gig::Region*> ignoredMinor;
1139                std::vector<gig::Region*> ignoredCritical;
1140                gig::Region* rgn = NULL;
1141                for (int key = 0; key < 128; ++key) {
1142                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
1143                    rgn = instr->GetRegion(key);
1144    
1145                    // ignore all regions which do not exactly match the dimension
1146                    // layout of the selected region where this operation was emitted
1147                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(maindimtype);
1148                    if (!dimdef) {
1149                        ignoredAll.push_back(rgn);
1150                        ignoredMinor.push_back(rgn);
1151                        continue;
1152                    }
1153                    if (dimdef->zones != maindimdef.zones) {
1154                        ignoredAll.push_back(rgn);
1155                        ignoredCritical.push_back(rgn);
1156                        continue;
1157                    }
1158    
1159                    rgn->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
1160                }
1161                if (!ignoredAll.empty()) {
1162                    Glib::ustring txt;
1163                    if (ignoredCritical.empty())
1164                        txt = ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type.");
1165                    else if (ignoredMinor.empty())
1166                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones!");
1167                    else
1168                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones (and ") +
1169                        ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type)!");
1170                    Gtk::MessageType type = (ignoredCritical.empty()) ? Gtk::MESSAGE_INFO : Gtk::MESSAGE_WARNING;
1171                    Gtk::MessageDialog msg(txt, false, type);
1172                    msg.run();
1173                }
1174            }
1175      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
1176          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1177          msg.run();          msg.run();
# Line 909  void DimRegionChooser::split_dimension_z Line 1186  void DimRegionChooser::split_dimension_z
1186  void DimRegionChooser::delete_dimension_zone() {  void DimRegionChooser::delete_dimension_zone() {
1187      printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);      printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1188      try {      try {
1189          region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);          if (!modifyallregions) {
1190                region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
1191            } else {
1192                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
1193                gig::dimension_def_t* pMaindimdef = region->GetDimensionDefinition(maindimtype);
1194                assert(pMaindimdef != NULL);
1195                // retain structure by value since the original region will be
1196                // modified in the loop below as well
1197                gig::dimension_def_t maindimdef = *pMaindimdef;
1198                std::vector<gig::Region*> ignoredAll;
1199                std::vector<gig::Region*> ignoredMinor;
1200                std::vector<gig::Region*> ignoredCritical;
1201                gig::Region* rgn = NULL;
1202                for (int key = 0; key < 128; ++key) {
1203                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
1204                    rgn = instr->GetRegion(key);
1205    
1206                    // ignore all regions which do not exactly match the dimension
1207                    // layout of the selected region where this operation was emitted
1208                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(maindimtype);
1209                    if (!dimdef) {
1210                        ignoredAll.push_back(rgn);
1211                        ignoredMinor.push_back(rgn);
1212                        continue;
1213                    }
1214                    if (dimdef->zones != maindimdef.zones) {
1215                        ignoredAll.push_back(rgn);
1216                        ignoredCritical.push_back(rgn);
1217                        continue;
1218                    }
1219    
1220                    rgn->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
1221                }
1222                if (!ignoredAll.empty()) {
1223                    Glib::ustring txt;
1224                    if (ignoredCritical.empty())
1225                        txt = ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type.");
1226                    else if (ignoredMinor.empty())
1227                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones!");
1228                    else
1229                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones (and ") +
1230                              ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type)!");
1231                    Gtk::MessageType type = (ignoredCritical.empty()) ? Gtk::MESSAGE_INFO : Gtk::MESSAGE_WARNING;
1232                    Gtk::MessageDialog msg(txt, false, type);
1233                    msg.run();
1234                }
1235            }
1236      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
1237          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1238          msg.run();          msg.run();
# Line 921  void DimRegionChooser::delete_dimension_ Line 1244  void DimRegionChooser::delete_dimension_
1244      refresh_all();      refresh_all();
1245  }  }
1246    
1247    // Cmd key on Mac, Ctrl key on all other OSs
1248    static const guint primaryKeyL =
1249        #if defined(__APPLE__)
1250        GDK_KEY_Meta_L;
1251        #else
1252        GDK_KEY_Control_L;
1253        #endif
1254    
1255    static const guint primaryKeyR =
1256        #if defined(__APPLE__)
1257        GDK_KEY_Meta_R;
1258        #else
1259        GDK_KEY_Control_R;
1260        #endif
1261    
1262  bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {  bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {
1263      //printf("key down\n");      //printf("key down 0x%x\n", key->keyval);
1264      if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)      if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)
1265          multiSelectKeyDown = true;          multiSelectKeyDown = true;
1266        if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
1267            primaryKeyDown = true;
1268        if (key->keyval == GDK_KEY_Shift_L || key->keyval == GDK_KEY_Shift_R)
1269            shiftKeyDown = true;
1270    
1271        //FIXME: hmm, for some reason GDKMM does not fire arrow key down events, so we are doing those handlers in the key up handler instead for now
1272        /*if (key->keyval == GDK_KEY_Left)
1273            select_prev_dimzone();
1274        if (key->keyval == GDK_KEY_Right)
1275            select_next_dimzone();
1276        if (key->keyval == GDK_KEY_Up)
1277            select_prev_dimension();
1278        if (key->keyval == GDK_KEY_Down)
1279            select_next_dimension();*/
1280        return false;
1281  }  }
1282    
1283  bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {  bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {
1284      //printf("key up\n");      //printf("key up 0x%x\n", key->keyval);
1285      if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)      if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)
1286          multiSelectKeyDown = false;          multiSelectKeyDown = false;
1287        if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
1288            primaryKeyDown = false;
1289        if (key->keyval == GDK_KEY_Shift_L || key->keyval == GDK_KEY_Shift_R)
1290            shiftKeyDown = false;
1291    
1292        if (!has_focus()) return false;
1293    
1294        // avoid conflict with Ctrl+Left and Ctrl+Right accelerators on mainwindow
1295        // (which is supposed to switch between regions)
1296        if (primaryKeyDown) return false;
1297    
1298        // avoid conflict with Alt+Shift+Left and Alt+Shift+Right accelerators on
1299        // mainwindow
1300        if (shiftKeyDown) return false;
1301    
1302        if (key->keyval == GDK_KEY_Left)
1303            select_prev_dimzone();
1304        if (key->keyval == GDK_KEY_Right)
1305            select_next_dimzone();
1306        if (key->keyval == GDK_KEY_Up)
1307            select_prev_dimension();
1308        if (key->keyval == GDK_KEY_Down)
1309            select_next_dimension();
1310    
1311        return false;
1312    }
1313    
1314    void DimRegionChooser::resetSelectedZones() {
1315        this->dimzones.clear();
1316        if (!region) {
1317            queue_draw(); // redraw required parts
1318            return;
1319        }
1320        if (maindimregno < 0 || maindimregno >= region->DimensionRegions) {
1321            queue_draw(); // redraw required parts
1322            return;
1323        }
1324        if (!region->pDimensionRegions[maindimregno]) {
1325            queue_draw(); // redraw required parts
1326            return;
1327        }
1328        gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];
1329    
1330        bool isValidZone;
1331        this->maindimcase = dimensionCaseOf(dimrgn);
1332    
1333        for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();
1334             it != this->maindimcase.end(); ++it)
1335        {
1336            this->dimzones[it->first].insert(it->second);
1337        }
1338    
1339        // redraw required parts
1340        queue_draw();
1341    }
1342    
1343    bool DimRegionChooser::select_dimregion(gig::DimensionRegion* dimrgn) {
1344        if (!region) return false; //.selection failed
1345    
1346        for (int dr = 0; dr < region->DimensionRegions && region->pDimensionRegions[dr]; ++dr) {
1347            if (region->pDimensionRegions[dr] == dimrgn) {
1348                // reset dim region zone selection to the requested specific dim region case
1349                maindimregno = dr;
1350                resetSelectedZones();
1351    
1352                // emit signal that dimregion selection has changed, for external entities
1353                dimregion_selected();
1354    
1355                return true; // selection success
1356            }
1357        }
1358    
1359        return false; //.selection failed
1360    }
1361    
1362    void DimRegionChooser::select_next_dimzone(bool add) {
1363        select_dimzone_by_dir(+1, add);
1364    }
1365    
1366    void DimRegionChooser::select_prev_dimzone(bool add) {
1367        select_dimzone_by_dir(-1, add);
1368    }
1369    
1370    void DimRegionChooser::select_dimzone_by_dir(int dir, bool add) {
1371        if (!region) return;
1372        if (!region->Dimensions) return;
1373        if (focus_line < 0) focus_line = 0;
1374        if (focus_line >= region->Dimensions) focus_line = region->Dimensions - 1;
1375    
1376        maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1377        if (maindimtype == gig::dimension_none) {
1378            printf("maindimtype -> none\n");
1379            return;
1380        }
1381    
1382        if (maindimcase.empty()) {
1383            maindimcase = dimensionCaseOf(region->pDimensionRegions[maindimregno]);
1384            if (maindimcase.empty()) {
1385                printf("caseOfDimregion(%d) -> empty\n", maindimregno);
1386                return;
1387            }
1388        }
1389    
1390        int z = (dir > 0) ? maindimcase[maindimtype] + 1 : maindimcase[maindimtype] - 1;
1391        if (z < 0) z = 0;
1392        if (z >= region->pDimensionDefinitions[focus_line].zones)
1393            z = region->pDimensionDefinitions[focus_line].zones - 1;
1394    
1395        maindimcase[maindimtype] = z;
1396    
1397        ::gig::DimensionRegion* dr = dimensionRegionMatching(maindimcase, region);
1398        if (!dr) {
1399            printf("select_dimzone_by_dir(%d) -> !dr\n", dir);
1400            return;
1401        }
1402    
1403        maindimregno = getDimensionRegionIndex(dr);
1404    
1405        if (!add) {
1406            // reset selected dimregion zones
1407            dimzones.clear();
1408        }
1409        for (DimensionCase::const_iterator it = maindimcase.begin();
1410             it != maindimcase.end(); ++it)
1411        {
1412            dimzones[it->first].insert(it->second);
1413        }
1414    
1415        dimregion_selected();
1416    
1417        // disabled: would overwrite dimregno with wrong value
1418        //refresh_all();
1419        // so requesting just a raw repaint instead:
1420        queue_draw();
1421    }
1422    
1423    void DimRegionChooser::select_next_dimension() {
1424        if (!region) return;
1425        focus_line++;
1426        if (focus_line >= region->Dimensions)
1427            focus_line = region->Dimensions - 1;
1428        this->maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1429        queue_draw();
1430    }
1431    
1432    void DimRegionChooser::select_prev_dimension() {
1433        if (!region) return;
1434        focus_line--;
1435        if (focus_line < 0)
1436            focus_line = 0;
1437        this->maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1438        queue_draw();
1439  }  }
1440    
1441  gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {  gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {

Legend:
Removed from v.2626  
changed lines
  Added in v.3147

  ViewVC Help
Powered by ViewVC