/[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 2462 by schoenebeck, Wed Sep 4 20:23:05 2013 UTC revision 3105 by schoenebeck, Fri Feb 10 18:40:26 2017 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2011 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 <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
24  #include <gdkmm/general.h>  #include <gdkmm/general.h>
25    #include <glibmm/stringutils.h>
26    #include <glibmm/ustring.h>
27    #include <gtkmm/messagedialog.h>
28    #include <assert.h>
29    
30  #include "global.h"  #include "global.h"
31    
32  DimRegionChooser::DimRegionChooser() :  // taken from gdk/gdkkeysyms.h
33    // (define on demand, to avoid unnecessary dev lib package build dependency)
34    #ifndef GDK_KEY_Control_L
35    # define GDK_KEY_Control_L 0xffe3
36    #endif
37    #ifndef GDK_KEY_Control_R
38    # define GDK_KEY_Control_R 0xffe4
39    #endif
40    
41    static std::map<gig::dimension_t,int> caseOfDimRegion(gig::DimensionRegion* dr, bool* isValidZone) {
42        std::map<gig::dimension_t,int> dimCase;
43        if (!dr) {
44            *isValidZone = false;
45            return dimCase;
46        }
47    
48        gig::Region* rgn = (gig::Region*) dr->GetParent();
49    
50        // find the dimension region index of the passed dimension region
51        int drIndex;
52        for (drIndex = 0; drIndex < 256; ++drIndex)
53            if (rgn->pDimensionRegions[drIndex] == dr)
54                break;
55    
56        // not found in region, something's horribly wrong
57        if (drIndex == 256) {
58            fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");
59            *isValidZone = false;
60            return std::map<gig::dimension_t,int>();
61        }
62    
63        for (int d = 0, baseBits = 0; d < rgn->Dimensions; ++d) {
64            const int bits = rgn->pDimensionDefinitions[d].bits;
65            dimCase[rgn->pDimensionDefinitions[d].dimension] =
66                (drIndex >> baseBits) & ((1 << bits) - 1);
67            baseBits += bits;
68            // there are also DimensionRegion objects of unused zones, skip them
69            if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {
70                *isValidZone = false;
71                return std::map<gig::dimension_t,int>();
72            }
73        }
74    
75        *isValidZone = true;
76        return dimCase;
77    }
78    
79    DimRegionChooser::DimRegionChooser(Gtk::Window& window) :
80      red("#8070ff"),      red("#8070ff"),
81      black("black"),      black("black"),
82      white("white")      white("white")
83  {  {
84      instrument = 0;      instrument = 0;
85      region = 0;      region = 0;
86      dimregno = -1;      maindimregno = -1;
87      focus_line = 0;      focus_line = 0;
88      resize.active = false;      resize.active = false;
89      cursor_is_resize = false;      cursor_is_resize = false;
90      h = 20;      h = 24;
91        multiSelectKeyDown = false;
92        modifybothchannels = modifyalldimregs = modifybothchannels = false;
93      set_can_focus();      set_can_focus();
94    
95        const Glib::ustring txtUseCheckBoxAllRegions =
96            _("Use checkbox 'all regions' to control whether this should apply to all regions.");
97    
98        actionGroup = Gtk::ActionGroup::create();
99        actionSplitDimZone = Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone"), txtUseCheckBoxAllRegions);
100        actionSplitDimZone->set_tooltip(txtUseCheckBoxAllRegions); //FIXME: doesn't work? why???
101        actionGroup->add(
102            actionSplitDimZone,
103            sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)
104        );
105        actionDeleteDimZone = Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone"), txtUseCheckBoxAllRegions);
106        actionDeleteDimZone->set_tooltip(txtUseCheckBoxAllRegions); //FIXME: doesn't work? why???
107        actionGroup->add(
108            actionDeleteDimZone,
109            sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)
110        );
111    
112        uiManager = Gtk::UIManager::create();
113        uiManager->insert_action_group(actionGroup);
114        Glib::ustring ui_info =
115            "<ui>"
116            "  <popup name='PopupMenuInsideDimRegion'>"
117            "    <menuitem action='SplitDimZone'/>"
118            "    <menuitem action='DeleteDimZone'/>"
119            "  </popup>"
120    //         "  <popup name='PopupMenuOutsideDimRegion'>"
121    //         "    <menuitem action='Add'/>"
122    //         "  </popup>"
123            "</ui>";
124        uiManager->add_ui_from_string(ui_info);
125    
126        popup_menu_inside_dimregion = dynamic_cast<Gtk::Menu*>(
127            uiManager->get_widget("/PopupMenuInsideDimRegion"));
128    //     popup_menu_outside_dimregion = dynamic_cast<Gtk::Menu*>(
129    //         uiManager->get_widget("/PopupMenuOutsideDimRegion"));
130    
131      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |
132                 Gdk::POINTER_MOTION_HINT_MASK);                 Gdk::POINTER_MOTION_HINT_MASK);
133    
     for (int i = 0 ; i < 256 ; i++) dimvalue[i] = 0;  
134      labels_changed = true;      labels_changed = true;
135    
136        set_tooltip_text(_(
137            "Right click here for options on altering dimension zones. Press and "
138            "hold CTRL key for selecting multiple dimension zones simultaniously."
139        ));
140        
141        window.signal_key_press_event().connect(
142            sigc::mem_fun(*this, &DimRegionChooser::onKeyPressed)
143        );
144        window.signal_key_release_event().connect(
145            sigc::mem_fun(*this, &DimRegionChooser::onKeyReleased)
146        );
147  }  }
148    
149  DimRegionChooser::~DimRegionChooser()  DimRegionChooser::~DimRegionChooser()
150  {  {
151  }  }
152    
153    void DimRegionChooser::setModifyBothChannels(bool b) {
154        modifybothchannels = b;
155    }
156    
157    void DimRegionChooser::setModifyAllDimensionRegions(bool b) {
158        modifyalldimregs = b;
159    }
160    
161    void DimRegionChooser::setModifyAllRegions(bool b) {
162        modifyallregions = b;
163    
164        actionDeleteDimZone->set_label(b ? _("Delete Dimension Zone [ALL REGIONS]") : _("Delete Dimension Zone"));
165        actionSplitDimZone->set_label(b ? _("Split Dimensions Zone [ALL REGIONS]") : _("Split Dimensions Zone"));
166    }
167    
168  #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
169  bool DimRegionChooser::on_expose_event(GdkEventExpose* e)  bool DimRegionChooser::on_expose_event(GdkEventExpose* e)
170  {  {
# Line 58  bool DimRegionChooser::on_expose_event(G Line 175  bool DimRegionChooser::on_expose_event(G
175    
176      const Cairo::RefPtr<Cairo::Context>& cr =      const Cairo::RefPtr<Cairo::Context>& cr =
177          get_window()->create_cairo_context();          get_window()->create_cairo_context();
 #if 0  
 }  
 #endif  
178  #else  #else
179  bool DimRegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)  bool DimRegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
180  {  {
# Line 176  bool DimRegionChooser::on_draw(const Cai Line 290  bool DimRegionChooser::on_draw(const Cai
290      for (int i = 0 ; i < region->Dimensions ; i++) {      for (int i = 0 ; i < region->Dimensions ; i++) {
291          int nbZones = region->pDimensionDefinitions[i].zones;          int nbZones = region->pDimensionDefinitions[i].zones;
292          if (nbZones) {          if (nbZones) {
293                const gig::dimension_t dimension = region->pDimensionDefinitions[i].dimension;
294    
295              if (y >= clipy2) break;              if (y >= clipy2) break;
296              if (y + h > clipy1) {              if (y + h > clipy1) {
297                  // draw focus rectangle around dimension's label and zones                  // draw focus rectangle around dimension's label and zones
298                  if (has_focus() && focus_line == i) {                  if (has_focus() && focus_line == i) {
299  #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
300                      Gdk::Rectangle farea(0, y, 150, 20);                      Gdk::Rectangle farea(0, y, 150, h);
301                      get_style()->paint_focus(get_window(), get_state(), farea,                      get_style()->paint_focus(get_window(), get_state(), farea,
302                                               *this, "",                                               *this, "",
303                                               0, y, label_width, 20);                                               0, y, label_width, h);
304  #else  #else
305                      get_style_context()->render_focus(cr,                      get_style_context()->render_focus(cr,
306                                                        0, y, label_width, 20);                                                        0, y, label_width, h);
307  #endif  #endif
308                  }                  }
309    
# Line 206  bool DimRegionChooser::on_draw(const Cai Line 322  bool DimRegionChooser::on_draw(const Cai
322                  cr->fill();                  cr->fill();
323    
324                  int c = 0;                  int c = 0;
325                  if (dimregno >= 0) {                  if (maindimregno >= 0) {
326                      int mask =                      int mask =
327                          ~(((1 << region->pDimensionDefinitions[i].bits) - 1) <<                          ~(((1 << region->pDimensionDefinitions[i].bits) - 1) <<
328                            bitpos);                            bitpos);
329                      c = dimregno & mask; // mask away this dimension                      c = maindimregno & mask; // mask away this dimension
330                  }                  }
331                  bool customsplits =                  bool customsplits =
332                      ((region->pDimensionDefinitions[i].split_type ==                      ((region->pDimensionDefinitions[i].split_type ==
# Line 220  bool DimRegionChooser::on_draw(const Cai Line 336  bool DimRegionChooser::on_draw(const Cai
336                        gig::dimension_velocity &&                        gig::dimension_velocity &&
337                        region->pDimensionRegions[c]->VelocityUpperLimit));                        region->pDimensionRegions[c]->VelocityUpperLimit));
338    
339                  // draw dimension's zone borders                  // draw dimension zones
340                  Gdk::Cairo::set_source_rgba(cr, black);                  Gdk::Cairo::set_source_rgba(cr, black);
341                  if (customsplits) {                  if (customsplits) {
342                      cr->move_to(label_width + 0.5, y + 1);                      cr->move_to(label_width + 0.5, y + 1);
343                      cr->line_to(label_width + 0.5, y + h - 1);                      cr->line_to(label_width + 0.5, y + h - 1);
344                        int prevX = label_width;
345                        int prevUpperLimit = -1;
346    
347                      for (int j = 0 ; j < nbZones ; j++) {                      for (int j = 0 ; j < nbZones ; j++) {
348                            // draw dimension zone's borders for custom splits
349                          gig::DimensionRegion* d =                          gig::DimensionRegion* d =
350                              region->pDimensionRegions[c + (j << bitpos)];                              region->pDimensionRegions[c + (j << bitpos)];
351                          int upperLimit = d->DimensionUpperLimits[i];                          int upperLimit = d->DimensionUpperLimits[i];
# Line 236  bool DimRegionChooser::on_draw(const Cai Line 355  bool DimRegionChooser::on_draw(const Cai
355                              label_width;                              label_width;
356                          if (x >= clipx2) break;                          if (x >= clipx2) break;
357                          if (x < clipx1) continue;                          if (x < clipx1) continue;
358                            Gdk::Cairo::set_source_rgba(cr, black);
359                          cr->move_to(x + 0.5, y + 1);                          cr->move_to(x + 0.5, y + 1);
360                          cr->line_to(x + 0.5, y + h - 1);                          cr->line_to(x + 0.5, y + h - 1);
361                            cr->stroke();
362    
363                            // draw fill for zone
364                            bool isSelectedZone = this->dimzones[dimension].count(j);
365                            Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);
366                            cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
367                            cr->fill();
368    
369                            // draw text showing the beginning of the dimension zone
370                            // as numeric value to the user
371                            {
372                                Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
373                                layout->set_text(Glib::Ascii::dtostr(prevUpperLimit+1));
374                                Gdk::Cairo::set_source_rgba(cr, black);
375                                // get the text dimensions
376                                int text_width, text_height;
377                                layout->get_pixel_size(text_width, text_height);
378                                // move text to the left end of the dimension zone
379                                cr->move_to(prevX + 3, y + (h - text_height) / 2);
380    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
381                                pango_cairo_show_layout(cr->cobj(), layout->gobj());
382    #else
383                                layout->show_in_cairo_context(cr);
384    #endif
385                            }
386                            // draw text showing the end of the dimension zone
387                            // as numeric value to the user
388                            {
389                                Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
390                                layout->set_text(Glib::Ascii::dtostr(upperLimit));
391                                Gdk::Cairo::set_source_rgba(cr, black);
392                                // get the text dimensions
393                                int text_width, text_height;
394                                layout->get_pixel_size(text_width, text_height);
395                                // move text to the left end of the dimension zone
396                                cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
397    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
398                                pango_cairo_show_layout(cr->cobj(), layout->gobj());
399    #else
400                                layout->show_in_cairo_context(cr);
401    #endif
402                            }
403    
404                            prevX = x;
405                            prevUpperLimit = upperLimit;
406                      }                      }
407                  } else {                  } else {
408                        int prevX = 0;
409                      for (int j = 0 ; j <= nbZones ; j++) {                      for (int j = 0 ; j <= nbZones ; j++) {
410                            // draw dimension zone's borders for normal splits
411                          int x = int((w - label_width - 1) * j /                          int x = int((w - label_width - 1) * j /
412                                      double(nbZones) + 0.5) + label_width;                                      double(nbZones) + 0.5) + label_width;
413                          if (x >= clipx2) break;                          if (x >= clipx2) break;
414                          if (x < clipx1) continue;                          if (x < clipx1) continue;
415                            Gdk::Cairo::set_source_rgba(cr, black);
416                          cr->move_to(x + 0.5, y + 1);                          cr->move_to(x + 0.5, y + 1);
417                          cr->line_to(x + 0.5, y + h - 1);                          cr->line_to(x + 0.5, y + h - 1);
418                      }                          cr->stroke();
                 }  
                 cr->stroke();  
419    
420                  // draw fill for currently selected zone                          if (j != 0) {
421                  if (dimregno >= 0) {                              // draw fill for zone
422                      Gdk::Cairo::set_source_rgba(cr, red);                              bool isSelectedZone = this->dimzones[dimension].count(j-1);
423                      int dr = (dimregno >> bitpos) &                              Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);
424                          ((1 << region->pDimensionDefinitions[i].bits) - 1);                              cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
                       
                     int x1 = -1, x2 = -1;  
                     if (customsplits) {  
                         x1 = label_width;  
                         for (int j = 0 ; j < nbZones && x1 + 1 < clipx2 ; j++) {  
                             gig::DimensionRegion* d =  
                                 region->pDimensionRegions[c + (j << bitpos)];  
                             int upperLimit = d->DimensionUpperLimits[i];  
                             if (!upperLimit) {  
                                 upperLimit = d->VelocityUpperLimit;  
                             }  
                             int v = upperLimit + 1;  
                             x2 = int((w - label_width - 1) * v / 128.0 +  
                                      0.5) + label_width;  
                             if (j == dr && x1 < x2) {  
                                 cr->rectangle(x1 + 1, y + 1,  
                                               (x2 - x1) - 1, h - 2);  
                                 cr->fill();  
                                 break;  
                             }  
                             x1 = x2;  
                         }  
                     } else {  
                         if (dr < nbZones) {  
                             x1 = int((w - label_width - 1) * dr /  
                                      double(nbZones) + 0.5);  
                             x2 = int((w - label_width - 1) * (dr + 1) /  
                                      double(nbZones) + 0.5);  
                             cr->rectangle(label_width + x1 + 1, y + 1,  
                                           (x2 - x1) - 1, h - 2);  
425                              cr->fill();                              cr->fill();
                         }  
                     }  
426    
427                      // draw text showing the beginning of the dimension zone                              // draw text showing the beginning of the dimension zone
428                      // as numeric value to the user                              // as numeric value to the user
429                      if (x1 >= 0) {                              {
430                          Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
431                          int v = roundf(float(x1 - label_width) / float(w - label_width) * 127.f);                                  layout->set_text(Glib::Ascii::dtostr((j-1) * 128/nbZones));
432                          if (dr > 0) v++;                                  Gdk::Cairo::set_source_rgba(cr, black);
433                          layout->set_text(Glib::Ascii::dtostr(v));                                  // get the text dimensions
434                          Gdk::Cairo::set_source_rgba(cr, black);                                  int text_width, text_height;
435                          Pango::Rectangle rect = layout->get_logical_extents();                                  layout->get_pixel_size(text_width, text_height);
436                                                            // move text to the left end of the dimension zone
437                          int text_width, text_height;                                  cr->move_to(prevX + 3, y + (h - text_height) / 2);
                         // get the text dimensions  
                         layout->get_pixel_size(text_width, text_height);  
                         // move text to the right end of the dimension zone  
                         cr->move_to(x1 + 1, y + 1);  
438  #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
439                          pango_cairo_show_layout(cr->cobj(), layout->gobj());                                  pango_cairo_show_layout(cr->cobj(), layout->gobj());
440  #else  #else
441                          layout->show_in_cairo_context(cr);                                  layout->show_in_cairo_context(cr);
442  #endif  #endif
443                      }                              }
444                      // draw text showing the end of the dimension zone                              // draw text showing the end of the dimension zone
445                      // as numeric value to the user                              // as numeric value to the user
446                      if (x2 >= 0) {                              {
447                          Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
448                          const int v = roundf(float(x2 - label_width) / float(w - label_width) * 127.f);                                  layout->set_text(Glib::Ascii::dtostr(j * 128/nbZones - 1));
449                          layout->set_text(Glib::Ascii::dtostr(v));                                  Gdk::Cairo::set_source_rgba(cr, black);
450                          Gdk::Cairo::set_source_rgba(cr, black);                                  // get the text dimensions
451                          Pango::Rectangle rect = layout->get_logical_extents();                                  int text_width, text_height;
452                                                            layout->get_pixel_size(text_width, text_height);
453                          int text_width, text_height;                                  // move text to the left end of the dimension zone
454                          // get the text dimensions                                  cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
                         layout->get_pixel_size(text_width, text_height);  
                         // move text to the right end of the dimension zone  
                         cr->move_to(x2 - text_width - 1, y + 1);  
455  #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
456                          pango_cairo_show_layout(cr->cobj(), layout->gobj());                                  pango_cairo_show_layout(cr->cobj(), layout->gobj());
457  #else  #else
458                          layout->show_in_cairo_context(cr);                                  layout->show_in_cairo_context(cr);
459  #endif  #endif
460                      }                              }
461                            }
462                            prevX = x;
463                        }      
464                  }                  }
465              }              }
   
466              y += h;              y += h;
467          }          }
468          bitpos += region->pDimensionDefinitions[i].bits;          bitpos += region->pDimensionDefinitions[i].bits;
# Line 345  bool DimRegionChooser::on_draw(const Cai Line 474  bool DimRegionChooser::on_draw(const Cai
474  void DimRegionChooser::set_region(gig::Region* region)  void DimRegionChooser::set_region(gig::Region* region)
475  {  {
476      this->region = region;      this->region = region;
477      dimregno = 0;      maindimregno = 0;
478      nbDimensions = 0;      nbDimensions = 0;
479      if (region) {      if (region) {
480          int bitcount = 0;          int bitcount = 0;
# Line 353  void DimRegionChooser::set_region(gig::R Line 482  void DimRegionChooser::set_region(gig::R
482              if (region->pDimensionDefinitions[dim].bits == 0) continue;              if (region->pDimensionDefinitions[dim].bits == 0) continue;
483              nbDimensions++;              nbDimensions++;
484    
485              int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],              int z = std::min(maindimcase[region->pDimensionDefinitions[dim].dimension],
486                               region->pDimensionDefinitions[dim].zones - 1);                               region->pDimensionDefinitions[dim].zones - 1);
487              dimregno |= (z << bitcount);              maindimregno |= (z << bitcount);
488              bitcount += region->pDimensionDefinitions[dim].bits;              bitcount += region->pDimensionDefinitions[dim].bits;
489          }          }
         dimreg = region->pDimensionRegions[dimregno];  
     } else {  
         dimreg = 0;  
490      }      }
491      dimregion_selected();      dimregion_selected();
492      set_size_request(800, region ? nbDimensions * 20 : 0);      set_size_request(800, region ? nbDimensions * h : 0);
493    
494      labels_changed = true;      labels_changed = true;
495      queue_resize();      queue_resize();
496        queue_draw();
497  }  }
498    
499    void DimRegionChooser::refresh_all() {
500        set_region(region);
501    }
502    
503  void DimRegionChooser::get_dimregions(const gig::Region* region, bool stereo,  void DimRegionChooser::get_dimregions(const gig::Region* region, bool stereo,
504                                        std::set<gig::DimensionRegion*>& dimregs) const                                        std::set<gig::DimensionRegion*>& dimregs) const
505  {  {
506      int dimregno = 0;      for (int iDimRgn = 0; iDimRgn < 256; ++iDimRgn) {
507      int bitcount = 0;          gig::DimensionRegion* dimRgn = region->pDimensionRegions[iDimRgn];
508      int stereo_bit = 0;          if (!dimRgn) continue;
509      for (int dim = 0 ; dim < region->Dimensions ; dim++) {          bool isValidZone;
510          if (region->pDimensionDefinitions[dim].bits == 0) continue;          std::map<gig::dimension_t,int> dimCase = caseOfDimRegion(dimRgn, &isValidZone);
511          if (stereo &&          if (!isValidZone) continue;
512              region->pDimensionDefinitions[dim].dimension == gig::dimension_samplechannel) {          for (std::map<gig::dimension_t,int>::const_iterator it = dimCase.begin();
513              stereo_bit = (1 << bitcount);               it != dimCase.end(); ++it)
514          } else {          {
515              int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],              if (stereo && it->first == gig::dimension_samplechannel) continue; // is selected
516                               region->pDimensionDefinitions[dim].zones - 1);  
517              dimregno |= (z << bitcount);              std::map<gig::dimension_t, std::set<int> >::const_iterator itSelectedDimension =
518                    this->dimzones.find(it->first);
519                if (itSelectedDimension != this->dimzones.end() &&
520                    itSelectedDimension->second.count(it->second)) continue; // is selected
521    
522                goto notSelected;
523          }          }
524          bitcount += region->pDimensionDefinitions[dim].bits;  
525            dimregs.insert(dimRgn);
526    
527            notSelected:
528            ;
529      }      }
     dimregs.insert(region->pDimensionRegions[dimregno]);  
     if (stereo_bit) dimregs.insert(region->pDimensionRegions[dimregno | stereo_bit]);  
530  }  }
531    
532  void DimRegionChooser::update_after_resize()  void DimRegionChooser::update_after_resize()
533  {  {
534      if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {      const uint8_t upperLimit = resize.pos - 1;
535        gig::Instrument* instr = (gig::Instrument*)region->GetParent();
536    
537          int bitpos = 0;      int bitpos = 0;
538          for (int j = 0 ; j < resize.dimension ; j++) {      for (int j = 0 ; j < resize.dimension ; j++) {
539              bitpos += region->pDimensionDefinitions[j].bits;          bitpos += region->pDimensionDefinitions[j].bits;
540          }      }
541    
542        const int stereobitpos =
543            (modifybothchannels) ? baseBits(gig::dimension_samplechannel, region) : -1;
544    
545        // the velocity dimension must be handled differently than all other
546        // dimension types, because
547        // 1. it is currently the only dimension type which allows different zone
548        //    sizes for different cases
549        // 2. for v2 format VelocityUpperLimit has to be set, DimensionUpperLimits for v3
550        if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
551          int mask =          int mask =
552              ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);              ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
553          int c = dimregno & mask; // mask away this dimension          int c = maindimregno & mask; // mask away this dimension
554    
555          if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {          if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {
556              // the velocity dimension didn't previously have              // the velocity dimension didn't previously have
# Line 425  void DimRegionChooser::update_after_resi Line 573  void DimRegionChooser::update_after_resi
573              }              }
574          }          }
575    
576          gig::DimensionRegion* d = region->pDimensionRegions[c + resize.offset];          int index = c + (resize.zone << bitpos);
577            gig::DimensionRegion* d = region->pDimensionRegions[index];
578          // update both v2 and v3 values          // update both v2 and v3 values
579          d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;          d->DimensionUpperLimits[resize.dimension] = upperLimit;
580          d->VelocityUpperLimit = resize.pos - 1;          d->VelocityUpperLimit = upperLimit;
581            if (modifybothchannels && stereobitpos >= 0) { // do the same for the other audio channel's dimregion ...
582                gig::DimensionRegion* d = region->pDimensionRegions[index ^ (1 << stereobitpos)];
583                d->DimensionUpperLimits[resize.dimension] = upperLimit;
584                d->VelocityUpperLimit = upperLimit;
585            }
586    
587            if (modifyalldimregs) {
588                gig::Region* rgn = NULL;
589                for (int key = 0; key < 128; ++key) {
590                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
591                    rgn = instr->GetRegion(key);
592                    if (!modifyallregions && rgn != region) continue; // hack to reduce overall code amount a bit
593                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
594                    if (!dimdef) continue;
595                    if (dimdef->zones != resize.dimensionDef.zones) continue;
596                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
597                    assert(iDim >= 0 && iDim < rgn->Dimensions);
598    
599                    // the dimension layout might be completely different in this
600                    // region, so we have to recalculate bitpos etc for this region
601                    const int bitpos = baseBits(resize.dimensionDef.dimension, rgn);
602                    const int stencil = ~(((1 << dimdef->bits) - 1) << bitpos);
603                    const int selection = resize.zone << bitpos;
604    
605                    // primitive and inefficient loop implementation, however due to
606                    // this circumstance the loop code is much simpler, and its lack
607                    // of runtime efficiency should not be notable in practice
608                    for (int idr = 0; idr < 256; ++idr) {
609                        const int index = (idr & stencil) | selection;
610                        assert(index >= 0 && index < 256);
611                        gig::DimensionRegion* dr = rgn->pDimensionRegions[index];
612                        if (!dr) continue;
613                        dr->DimensionUpperLimits[iDim] = upperLimit;
614                        d->VelocityUpperLimit = upperLimit;
615                    }
616                }
617            } else if (modifyallregions) { // implies modifyalldimregs is false ...
618                // resolve the precise case we need to modify for all other regions
619                DimensionCase dimCase = dimensionCaseOf(d);
620                // apply the velocity upper limit change to that resolved dim case
621                // of all regions ...
622                gig::Region* rgn = NULL;
623                for (int key = 0; key < 128; ++key) {
624                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
625                    rgn = instr->GetRegion(key);
626                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
627                    if (!dimdef) continue;
628                    if (dimdef->zones != resize.dimensionDef.zones) continue;
629                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
630                    assert(iDim >= 0 && iDim < rgn->Dimensions);
631    
632                    std::vector<gig::DimensionRegion*> dimrgns = dimensionRegionsMatching(dimCase, rgn);
633                    for (int i = 0; i < dimrgns.size(); ++i) {
634                        gig::DimensionRegion* dr = dimrgns[i];
635                        dr->DimensionUpperLimits[iDim] = upperLimit;
636                        dr->VelocityUpperLimit = upperLimit;
637                    }
638                }
639            }
640      } else {      } else {
641          for (int i = 0 ; i < region->DimensionRegions ; ) {          for (int i = 0 ; i < region->DimensionRegions ; ) {
   
642              if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {              if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {
643                  // the dimension didn't previously have custom                  // the dimension didn't previously have custom
644                  // limits, so we have to set default limits for                  // limits, so we have to set default limits for
645                  // all the dimension regions                  // all the dimension regions
                 int bitpos = 0;  
                 for (int j = 0 ; j < resize.dimension ; j++) {  
                     bitpos += region->pDimensionDefinitions[j].bits;  
                 }  
646                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
647    
648                  for (int j = 0 ; j < nbZones ; j++) {                  for (int j = 0 ; j < nbZones ; j++) {
# Line 448  void DimRegionChooser::update_after_resi Line 650  void DimRegionChooser::update_after_resi
650                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
651                  }                  }
652              }              }
653              gig::DimensionRegion* d = region->pDimensionRegions[i + resize.offset];              int index = i + (resize.zone << bitpos);
654              d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;              gig::DimensionRegion* d = region->pDimensionRegions[index];
655                d->DimensionUpperLimits[resize.dimension] = upperLimit;
656    #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
657                if (modifybothchannels && stereobitpos >= 0) { // do the same for the other audio channel's dimregion ...
658                    gig::DimensionRegion* d = region->pDimensionRegions[index ^ (1 << stereobitpos)];
659                    d->DimensionUpperLimits[resize.dimension] = upperLimit;
660                }
661    #endif
662              int bitpos = 0;              int bitpos = 0;
663              int j;              int j;
664              for (j = 0 ; j < region->Dimensions ; j++) {              for (j = 0 ; j < region->Dimensions ; j++) {
# Line 464  void DimRegionChooser::update_after_resi Line 672  void DimRegionChooser::update_after_resi
672              if (j == region->Dimensions) break;              if (j == region->Dimensions) break;
673              i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);              i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
674          }          }
675    
676            if (modifyallregions) { // TODO: this code block could be merged with the similar (and more generalized) code block of the velocity dimension above
677                gig::Region* rgn = NULL;
678                for (int key = 0; key < 128; ++key) {
679                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
680                    rgn = instr->GetRegion(key);
681                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
682                    if (!dimdef) continue;
683                    if (dimdef->zones != resize.dimensionDef.zones) continue;
684                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
685                    assert(iDim >= 0 && iDim < rgn->Dimensions);
686    
687                    // the dimension layout might be completely different in this
688                    // region, so we have to recalculate bitpos etc for this region
689                    const int bitpos = baseBits(resize.dimensionDef.dimension, rgn);
690                    const int stencil = ~(((1 << dimdef->bits) - 1) << bitpos);
691                    const int selection = resize.zone << bitpos;
692    
693                    // this loop implementation is less efficient than the above's
694                    // loop implementation (which skips unnecessary dimension regions)
695                    // however this code is much simpler, and its lack of runtime
696                    // efficiency should not be notable in practice
697                    for (int idr = 0; idr < 256; ++idr) {
698                        const int index = (idr & stencil) | selection;
699                        assert(index >= 0 && index < 256);
700                        gig::DimensionRegion* dr = rgn->pDimensionRegions[index];
701                        if (!dr) continue;
702                        dr->DimensionUpperLimits[iDim] = upperLimit;
703                    }
704                }
705            }
706      }      }
707  }  }
708    
# Line 529  bool DimRegionChooser::on_button_press_e Line 768  bool DimRegionChooser::on_button_press_e
768              }              }
769    
770              int i = dim;              int i = dim;
771              if (dimregno < 0) dimregno = 0;              if (maindimregno < 0) maindimregno = 0;
772              int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);              int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);
773              int c = dimregno & mask; // mask away this dimension              int c = this->maindimregno & mask; // mask away this dimension
774    
775              bool customsplits =              bool customsplits =
776                  ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&                  ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&
# Line 561  bool DimRegionChooser::on_button_press_e Line 800  bool DimRegionChooser::on_button_press_e
800                     region->pDimensionDefinitions[dim].split_type,                     region->pDimensionDefinitions[dim].split_type,
801                     region->pDimensionDefinitions[dim].zones,                     region->pDimensionDefinitions[dim].zones,
802                     region->pDimensionDefinitions[dim].zone_size);                     region->pDimensionDefinitions[dim].zone_size);
803              dimvalue[region->pDimensionDefinitions[dim].dimension] = z;              this->maindimcase[region->pDimensionDefinitions[dim].dimension] = z;
804                this->maindimregno = c | (z << bitpos);
805              dimregno = c | (z << bitpos);              this->maindimtype = region->pDimensionDefinitions[dim].dimension;
806    
807                if (multiSelectKeyDown) {
808                    if (dimzones[this->maindimtype].count(z)) {
809                        if (dimzones[this->maindimtype].size() > 1) {
810                            dimzones[this->maindimtype].erase(z);
811                        }
812                    } else {
813                        dimzones[this->maindimtype].insert(z);
814                    }
815                } else {
816                    this->dimzones.clear();
817                    for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();
818                         it != this->maindimcase.end(); ++it)
819                    {
820                        this->dimzones[it->first].insert(it->second);
821                    }
822                }
823    
824              focus_line = dim;              focus_line = dim;
825              if (has_focus()) queue_draw();              if (has_focus()) queue_draw();
826              else grab_focus();              else grab_focus();
             dimreg = region->pDimensionRegions[dimregno];  
827              dimregion_selected();              dimregion_selected();
828    
829                if (event->button == 3) {
830                    printf("dimregion right click\n");
831                    popup_menu_inside_dimregion->popup(event->button, event->time);
832                }
833    
834                queue_draw();
835          }          }
836      }      }
837      return true;      return true;
# Line 607  bool DimRegionChooser::on_motion_notify_ Line 869  bool DimRegionChooser::on_motion_notify_
869    
870              resize.pos = k;              resize.pos = k;
871              update_after_resize();              update_after_resize();
872              get_window()->invalidate_rect(rect, false);              get_window()->invalidate_rect(rect, false); // not sufficient ...
873                queue_draw(); // ... so do a complete redraw instead.
874          }          }
875      } else {      } else {
876          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
# Line 643  bool DimRegionChooser::is_in_resize_zone Line 906  bool DimRegionChooser::is_in_resize_zone
906          int nbZones = region->pDimensionDefinitions[dim].zones;          int nbZones = region->pDimensionDefinitions[dim].zones;
907    
908          int c = 0;          int c = 0;
909          if (dimregno >= 0) {          if (maindimregno >= 0) {
910              int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);              int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);
911              c = dimregno & mask; // mask away this dimension              c = maindimregno & mask; // mask away this dimension
912          }          }
913          const bool customsplits =          const bool customsplits =
914              ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&              ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&
# Line 668  bool DimRegionChooser::is_in_resize_zone Line 931  bool DimRegionChooser::is_in_resize_zone
931                  if (x <= limitx - 2) break;                  if (x <= limitx - 2) break;
932                  if (x <= limitx + 2) {                  if (x <= limitx + 2) {
933                      resize.dimension = dim;                      resize.dimension = dim;
934                      resize.offset = iZone << bitpos;                      resize.dimensionDef = region->pDimensionDefinitions[dim];
935                        resize.zone = iZone;
936                      resize.pos = limit;                      resize.pos = limit;
937                      resize.min = prev_limit;                      resize.min = prev_limit;
938    
939                      int dr = (dimregno >> bitpos) &                      int dr = (maindimregno >> bitpos) &
940                          ((1 << region->pDimensionDefinitions[dim].bits) - 1);                          ((1 << region->pDimensionDefinitions[dim].bits) - 1);
941                      resize.selected = dr == iZone ? resize.left :                      resize.selected = dr == iZone ? resize.left :
942                          dr == iZone + 1 ? resize.right : resize.none;                          dr == iZone + 1 ? resize.right : resize.none;
# Line 709  sigc::signal<void>& DimRegionChooser::si Line 973  sigc::signal<void>& DimRegionChooser::si
973    
974  bool DimRegionChooser::on_focus(Gtk::DirectionType direction)  bool DimRegionChooser::on_focus(Gtk::DirectionType direction)
975  {  {
976      // 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
977      // fokus.      // to set focus
978      if (direction == Gtk::DIR_TAB_FORWARD ||      if (direction == Gtk::DIR_TAB_FORWARD ||
979          direction == Gtk::DIR_DOWN) {          direction == Gtk::DIR_DOWN) {
980          if (!has_focus()) {          if (!has_focus()) {
# Line 742  bool DimRegionChooser::on_focus(Gtk::Dir Line 1006  bool DimRegionChooser::on_focus(Gtk::Dir
1006              }              }
1007          }          }
1008      } else if (!has_focus()) {      } else if (!has_focus()) {
1009          // TODO: kolla att focus_line finns!          // TODO: check that focus_line exists
1010          grab_focus();          grab_focus();
1011          return true;          return true;
1012      } else {      } else {
1013          // TODO: öka eller minska värde!          // TODO: increase or decrease value
1014        }
1015        return false;
1016    }
1017    
1018    void DimRegionChooser::split_dimension_zone() {    
1019        printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1020        try {
1021            if (!modifyallregions) {
1022                region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
1023            } else {
1024                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
1025                gig::dimension_def_t* pMaindimdef = region->GetDimensionDefinition(maindimtype);
1026                assert(pMaindimdef != NULL);
1027                // retain structure by value since the original region will be
1028                // modified in the loop below as well
1029                gig::dimension_def_t maindimdef = *pMaindimdef;
1030                std::vector<gig::Region*> ignoredAll;
1031                std::vector<gig::Region*> ignoredMinor;
1032                std::vector<gig::Region*> ignoredCritical;
1033                gig::Region* rgn = NULL;
1034                for (int key = 0; key < 128; ++key) {
1035                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
1036                    rgn = instr->GetRegion(key);
1037    
1038                    // ignore all regions which do not exactly match the dimension
1039                    // layout of the selected region where this operation was emitted
1040                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(maindimtype);
1041                    if (!dimdef) {
1042                        ignoredAll.push_back(rgn);
1043                        ignoredMinor.push_back(rgn);
1044                        continue;
1045                    }
1046                    if (dimdef->zones != maindimdef.zones) {
1047                        ignoredAll.push_back(rgn);
1048                        ignoredCritical.push_back(rgn);
1049                        continue;
1050                    }
1051    
1052                    rgn->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
1053                }
1054                if (!ignoredAll.empty()) {
1055                    Glib::ustring txt;
1056                    if (ignoredCritical.empty())
1057                        txt = ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type.");
1058                    else if (ignoredMinor.empty())
1059                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones!");
1060                    else
1061                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones (and ") +
1062                        ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type)!");
1063                    Gtk::MessageType type = (ignoredCritical.empty()) ? Gtk::MESSAGE_INFO : Gtk::MESSAGE_WARNING;
1064                    Gtk::MessageDialog msg(txt, false, type);
1065                    msg.run();
1066                }
1067            }
1068        } catch (RIFF::Exception e) {
1069            Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1070            msg.run();
1071        } catch (...) {
1072            Glib::ustring txt = _("An unknown exception occurred!");
1073            Gtk::MessageDialog msg(txt, false, Gtk::MESSAGE_ERROR);
1074            msg.run();
1075      }      }
1076        refresh_all();
1077    }
1078    
1079    void DimRegionChooser::delete_dimension_zone() {
1080        printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1081        try {
1082            if (!modifyallregions) {
1083                region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
1084            } else {
1085                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
1086                gig::dimension_def_t* pMaindimdef = region->GetDimensionDefinition(maindimtype);
1087                assert(pMaindimdef != NULL);
1088                // retain structure by value since the original region will be
1089                // modified in the loop below as well
1090                gig::dimension_def_t maindimdef = *pMaindimdef;
1091                std::vector<gig::Region*> ignoredAll;
1092                std::vector<gig::Region*> ignoredMinor;
1093                std::vector<gig::Region*> ignoredCritical;
1094                gig::Region* rgn = NULL;
1095                for (int key = 0; key < 128; ++key) {
1096                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
1097                    rgn = instr->GetRegion(key);
1098    
1099                    // ignore all regions which do not exactly match the dimension
1100                    // layout of the selected region where this operation was emitted
1101                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(maindimtype);
1102                    if (!dimdef) {
1103                        ignoredAll.push_back(rgn);
1104                        ignoredMinor.push_back(rgn);
1105                        continue;
1106                    }
1107                    if (dimdef->zones != maindimdef.zones) {
1108                        ignoredAll.push_back(rgn);
1109                        ignoredCritical.push_back(rgn);
1110                        continue;
1111                    }
1112    
1113                    rgn->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
1114                }
1115                if (!ignoredAll.empty()) {
1116                    Glib::ustring txt;
1117                    if (ignoredCritical.empty())
1118                        txt = ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type.");
1119                    else if (ignoredMinor.empty())
1120                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones!");
1121                    else
1122                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones (and ") +
1123                              ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type)!");
1124                    Gtk::MessageType type = (ignoredCritical.empty()) ? Gtk::MESSAGE_INFO : Gtk::MESSAGE_WARNING;
1125                    Gtk::MessageDialog msg(txt, false, type);
1126                    msg.run();
1127                }
1128            }
1129        } catch (RIFF::Exception e) {
1130            Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1131            msg.run();
1132        } catch (...) {
1133            Glib::ustring txt = _("An unknown exception occurred!");
1134            Gtk::MessageDialog msg(txt, false, Gtk::MESSAGE_ERROR);
1135            msg.run();
1136        }
1137        refresh_all();
1138    }
1139    
1140    bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {
1141        //printf("key down\n");
1142        if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)
1143            multiSelectKeyDown = true;
1144        return false;
1145    }
1146    
1147    bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {
1148        //printf("key up\n");
1149        if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)
1150            multiSelectKeyDown = false;
1151        return false;
1152    }
1153    
1154    void DimRegionChooser::resetSelectedZones() {
1155        this->dimzones.clear();
1156        if (!region) {
1157            queue_draw(); // redraw required parts
1158            return;
1159        }
1160        if (maindimregno < 0 || maindimregno >= region->DimensionRegions) {
1161            queue_draw(); // redraw required parts
1162            return;
1163        }
1164        if (!region->pDimensionRegions[maindimregno]) {
1165            queue_draw(); // redraw required parts
1166            return;
1167        }
1168        gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];
1169    
1170        bool isValidZone;
1171        this->maindimcase = caseOfDimRegion(dimrgn, &isValidZone);
1172        if (!isValidZone) {
1173            queue_draw(); // redraw required parts
1174            return;
1175        }
1176    
1177        for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();
1178             it != this->maindimcase.end(); ++it)
1179        {
1180            this->dimzones[it->first].insert(it->second);
1181        }
1182    
1183        // redraw required parts
1184        queue_draw();
1185    }
1186    
1187    bool DimRegionChooser::select_dimregion(gig::DimensionRegion* dimrgn) {
1188        if (!region) return false; //.selection failed
1189    
1190        for (int dr = 0; dr < region->DimensionRegions && region->pDimensionRegions[dr]; ++dr) {
1191            if (region->pDimensionRegions[dr] == dimrgn) {
1192                // reset dim region zone selection to the requested specific dim region case
1193                maindimregno = dr;
1194                resetSelectedZones();
1195    
1196                // emit signal that dimregion selection has changed, for external entities
1197                dimregion_selected();
1198    
1199                return true; // selection success
1200            }
1201        }
1202    
1203        return false; //.selection failed
1204    }
1205    
1206    gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {
1207        if (!region) return NULL;
1208        return region->pDimensionRegions[maindimregno];
1209  }  }

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

  ViewVC Help
Powered by ViewVC