/[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 3089 by schoenebeck, Sun Jan 15 19:18:39 2017 UTC revision 3147 by schoenebeck, Wed May 3 21:23:16 2017 UTC
# Line 20  Line 20 
20  #include <gtkmm/box.h>  #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>
# Line 28  Line 29 
29  #include <assert.h>  #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 57  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 68  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 77  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 = 24;      h = 24;
150      multiSelectKeyDown = false;      multiSelectKeyDown = false;
151        primaryKeyDown = false;
152        shiftKeyDown = false;
153      modifybothchannels = modifyalldimregs = modifybothchannels = false;      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 145  DimRegionChooser::~DimRegionChooser() Line 213  DimRegionChooser::~DimRegionChooser()
213    
214  void DimRegionChooser::setModifyBothChannels(bool b) {  void DimRegionChooser::setModifyBothChannels(bool b) {
215      modifybothchannels = b;      modifybothchannels = b;
216        // redraw required parts
217        queue_draw();
218  }  }
219    
220  void DimRegionChooser::setModifyAllDimensionRegions(bool b) {  void DimRegionChooser::setModifyAllDimensionRegions(bool b) {
221      modifyalldimregs = b;      modifyalldimregs = b;
222        // redraw required parts
223        queue_draw();
224  }  }
225    
226  void DimRegionChooser::setModifyAllRegions(bool b) {  void DimRegionChooser::setModifyAllRegions(bool b) {
227      modifyallregions = b;      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
# Line 243  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 352  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 410  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 1008  bool DimRegionChooser::on_focus(Gtk::Dir Line 1125  bool DimRegionChooser::on_focus(Gtk::Dir
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 1023  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 1035  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;      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;      return false;
1312  }  }
1313    
# Line 1066  void DimRegionChooser::resetSelectedZone Line 1328  void DimRegionChooser::resetSelectedZone
1328      gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];      gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];
1329    
1330      bool isValidZone;      bool isValidZone;
1331      this->maindimcase = caseOfDimRegion(dimrgn, &isValidZone);      this->maindimcase = dimensionCaseOf(dimrgn);
     if (!isValidZone) {  
         queue_draw(); // redraw required parts  
         return;  
     }  
1332    
1333      for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();      for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();
1334           it != this->maindimcase.end(); ++it)           it != this->maindimcase.end(); ++it)
# Line 1101  bool DimRegionChooser::select_dimregion( Line 1359  bool DimRegionChooser::select_dimregion(
1359      return false; //.selection failed      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 {
1442      if (!region) return NULL;      if (!region) return NULL;
1443      return region->pDimensionRegions[maindimregno];      return region->pDimensionRegions[maindimregno];

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

  ViewVC Help
Powered by ViewVC