/[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 3158 by schoenebeck, Mon May 8 18:05:35 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>
27    #include <gtkmm/stock.h>
28  #include <glibmm/ustring.h>  #include <glibmm/ustring.h>
29  #include <gtkmm/messagedialog.h>  #include <gtkmm/messagedialog.h>
30  #include <assert.h>  #include <assert.h>
31    
32  #include "global.h"  #include "global.h"
33    #include "gfx/builtinpix.h"
34    
35  // taken from gdk/gdkkeysyms.h  //TODO: this function and dimensionCaseOf() from global.h are duplicates, eliminate either one of them!
36  // (define on demand, to avoid unnecessary dev lib package build dependency)  static DimensionCase caseOfDimRegion(gig::DimensionRegion* dr, bool* isValidZone) {
37  #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;  
38      if (!dr) {      if (!dr) {
39          *isValidZone = false;          *isValidZone = false;
40          return dimCase;          return dimCase;
# Line 57  static std::map<gig::dimension_t,int> ca Line 52  static std::map<gig::dimension_t,int> ca
52      if (drIndex == 256) {      if (drIndex == 256) {
53          fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");          fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");
54          *isValidZone = false;          *isValidZone = false;
55          return std::map<gig::dimension_t,int>();          return DimensionCase();
56      }      }
57    
58      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 63  static std::map<gig::dimension_t,int> ca
63          // there are also DimensionRegion objects of unused zones, skip them          // there are also DimensionRegion objects of unused zones, skip them
64          if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {          if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {
65              *isValidZone = false;              *isValidZone = false;
66              return std::map<gig::dimension_t,int>();              return DimensionCase();
67          }          }
68      }      }
69    
# Line 77  static std::map<gig::dimension_t,int> ca Line 72  static std::map<gig::dimension_t,int> ca
72  }  }
73    
74  DimRegionChooser::DimRegionChooser(Gtk::Window& window) :  DimRegionChooser::DimRegionChooser(Gtk::Window& window) :
75      red("#8070ff"),      red("#ff476e"),
76        blue("#4796ff"),
77      black("black"),      black("black"),
78      white("white")      white("white")
79  {  {
80        // make sure blue hatched pattern pixmap is loaded
81        loadBuiltInPix();
82    
83        // create blue hatched pattern
84        {
85            const int width = blueHatchedPattern->get_width();
86            const int height = blueHatchedPattern->get_height();
87            const int stride = blueHatchedPattern->get_rowstride();
88    
89            // manually convert from RGBA to ARGB
90            this->blueHatchedPatternARGB = blueHatchedPattern->copy();
91            const int pixelSize = stride / width;
92            const int totalPixels = width * height;
93            assert(pixelSize == 4);
94            unsigned char* ptr = this->blueHatchedPatternARGB->get_pixels();
95            for (int iPixel = 0; iPixel < totalPixels; ++iPixel, ptr += pixelSize) {
96                const unsigned char r = ptr[0];
97                const unsigned char g = ptr[1];
98                const unsigned char b = ptr[2];
99                const unsigned char a = ptr[3];
100                ptr[0] = b;
101                ptr[1] = g;
102                ptr[2] = r;
103                ptr[3] = a;
104            }
105    
106            Cairo::RefPtr<Cairo::ImageSurface> imageSurface = Cairo::ImageSurface::create(
107                this->blueHatchedPatternARGB->get_pixels(), Cairo::FORMAT_ARGB32, width, height, stride
108            );
109            this->blueHatchedSurfacePattern = Cairo::SurfacePattern::create(imageSurface);
110            this->blueHatchedSurfacePattern->set_extend(Cairo::EXTEND_REPEAT);
111        }
112    
113        // create gray blue hatched pattern
114        {
115            const int width = grayBlueHatchedPattern->get_width();
116            const int height = grayBlueHatchedPattern->get_height();
117            const int stride = grayBlueHatchedPattern->get_rowstride();
118    
119            // manually convert from RGBA to ARGB
120            this->grayBlueHatchedPatternARGB = grayBlueHatchedPattern->copy();
121            const int pixelSize = stride / width;
122            const int totalPixels = width * height;
123            assert(pixelSize == 4);
124            unsigned char* ptr = this->grayBlueHatchedPatternARGB->get_pixels();
125            for (int iPixel = 0; iPixel < totalPixels; ++iPixel, ptr += pixelSize) {
126                const unsigned char r = ptr[0];
127                const unsigned char g = ptr[1];
128                const unsigned char b = ptr[2];
129                const unsigned char a = ptr[3];
130                ptr[0] = b;
131                ptr[1] = g;
132                ptr[2] = r;
133                ptr[3] = a;
134            }
135    
136            Cairo::RefPtr<Cairo::ImageSurface> imageSurface = Cairo::ImageSurface::create(
137                this->grayBlueHatchedPatternARGB->get_pixels(), Cairo::FORMAT_ARGB32, width, height, stride
138            );
139            this->grayBlueHatchedSurfacePattern = Cairo::SurfacePattern::create(imageSurface);
140            this->grayBlueHatchedSurfacePattern->set_extend(Cairo::EXTEND_REPEAT);
141        }
142    
143      instrument = 0;      instrument = 0;
144      region = 0;      region = 0;
145      maindimregno = -1;      maindimregno = -1;
146        maindimtype = gig::dimension_none; // initialize with invalid dimension type
147      focus_line = 0;      focus_line = 0;
148      resize.active = false;      resize.active = false;
149      cursor_is_resize = false;      cursor_is_resize = false;
150      h = 24;      h = 24;
151      multiSelectKeyDown = false;      multiSelectKeyDown = false;
152        primaryKeyDown = false;
153        shiftKeyDown = false;
154      modifybothchannels = modifyalldimregs = modifybothchannels = false;      modifybothchannels = modifyalldimregs = modifybothchannels = false;
155      set_can_focus();      set_can_focus();
156    
157        const Glib::ustring txtUseCheckBoxAllRegions =
158            _("Use checkbox 'all regions' to control whether this should apply to all regions.");
159    
160      actionGroup = Gtk::ActionGroup::create();      actionGroup = Gtk::ActionGroup::create();
161        actionSplitDimZone = Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone"), txtUseCheckBoxAllRegions);
162        actionSplitDimZone->set_tooltip(txtUseCheckBoxAllRegions); //FIXME: doesn't work? why???
163      actionGroup->add(      actionGroup->add(
164          Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone")),          actionSplitDimZone,
165          sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)          sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)
166      );      );
167        actionDeleteDimZone = Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone"), txtUseCheckBoxAllRegions);
168        actionDeleteDimZone->set_tooltip(txtUseCheckBoxAllRegions); //FIXME: doesn't work? why???
169      actionGroup->add(      actionGroup->add(
170          Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone")),          actionDeleteDimZone,
171          sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)          sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)
172      );      );
173    
# Line 145  DimRegionChooser::~DimRegionChooser() Line 214  DimRegionChooser::~DimRegionChooser()
214    
215  void DimRegionChooser::setModifyBothChannels(bool b) {  void DimRegionChooser::setModifyBothChannels(bool b) {
216      modifybothchannels = b;      modifybothchannels = b;
217        // redraw required parts
218        queue_draw();
219  }  }
220    
221  void DimRegionChooser::setModifyAllDimensionRegions(bool b) {  void DimRegionChooser::setModifyAllDimensionRegions(bool b) {
222      modifyalldimregs = b;      modifyalldimregs = b;
223        // redraw required parts
224        queue_draw();
225  }  }
226    
227  void DimRegionChooser::setModifyAllRegions(bool b) {  void DimRegionChooser::setModifyAllRegions(bool b) {
228      modifyallregions = b;      modifyallregions = b;
229    
230        actionDeleteDimZone->set_label(b ? _("Delete Dimension Zone [ALL REGIONS]") : _("Delete Dimension Zone"));
231        actionSplitDimZone->set_label(b ? _("Split Dimensions Zone [ALL REGIONS]") : _("Split Dimensions Zone"));
232    
233        // redraw required parts
234        queue_draw();
235  }  }
236    
237  #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 322  bool DimRegionChooser::on_draw(const Cai
322                      dstr = dstrbuf;                      dstr = dstrbuf;
323                      break;                      break;
324                  }                  }
                 layout->set_text(dstr);  
325    
326                    // Since bold font yields in larger label width, we first always
327                    // set the bold text variant, retrieve its dimensions (as worst
328                    // case dimensions of the label) ...
329                    layout->set_markup("<b>" + Glib::ustring(dstr) + "</b>");
330                  Pango::Rectangle rectangle = layout->get_logical_extents();                  Pango::Rectangle rectangle = layout->get_logical_extents();
331                    // ... and then reset the label to regular font style in case
332                    // the line is not selected. Otherwise the right hand side
333                    // actual dimension zones would jump around on selection change.
334                    bool isSelectedLine = (focus_line == i);
335                    if (!isSelectedLine)
336                        layout->set_markup(dstr);
337    
338                  double text_w = double(rectangle.get_width()) / Pango::SCALE;                  double text_w = double(rectangle.get_width()) / Pango::SCALE;
339                  if (text_w > maxwidth) maxwidth = text_w;                  if (text_w > maxwidth) maxwidth = text_w;
340    
# Line 352  bool DimRegionChooser::on_draw(const Cai Line 441  bool DimRegionChooser::on_draw(const Cai
441    
442                          // draw fill for zone                          // draw fill for zone
443                          bool isSelectedZone = this->dimzones[dimension].count(j);                          bool isSelectedZone = this->dimzones[dimension].count(j);
444                          Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);                          bool isMainSelection =
445                                this->maindimcase.find(dimension) != this->maindimcase.end() &&
446                                this->maindimcase[dimension] == j;
447                            bool isCheckBoxSelected =
448                                modifyalldimregs ||
449                                (modifybothchannels &&
450                                    dimension == gig::dimension_samplechannel);
451                            if (isMainSelection)
452                                Gdk::Cairo::set_source_rgba(cr, blue);
453                            else if (isSelectedZone)
454                                cr->set_source(blueHatchedSurfacePattern);
455                            else if (isCheckBoxSelected)
456                                cr->set_source(grayBlueHatchedSurfacePattern);
457                            else
458                                Gdk::Cairo::set_source_rgba(cr, white);
459    
460                          cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);                          cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
461                          cr->fill();                          cr->fill();
462    
# Line 410  bool DimRegionChooser::on_draw(const Cai Line 514  bool DimRegionChooser::on_draw(const Cai
514                          if (j != 0) {                          if (j != 0) {
515                              // draw fill for zone                              // draw fill for zone
516                              bool isSelectedZone = this->dimzones[dimension].count(j-1);                              bool isSelectedZone = this->dimzones[dimension].count(j-1);
517                              Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);                              bool isMainSelection =
518                                    this->maindimcase.find(dimension) != this->maindimcase.end() &&
519                                    this->maindimcase[dimension] == (j-1);
520                                bool isCheckBoxSelected =
521                                    modifyalldimregs ||
522                                    (modifybothchannels &&
523                                        dimension == gig::dimension_samplechannel);
524                                if (isMainSelection)
525                                    Gdk::Cairo::set_source_rgba(cr, blue);
526                                else if (isSelectedZone)
527                                    cr->set_source(blueHatchedSurfacePattern);
528                                else if (isCheckBoxSelected)
529                                    cr->set_source(grayBlueHatchedSurfacePattern);
530                                else
531                                    Gdk::Cairo::set_source_rgba(cr, white);
532                              cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);                              cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
533                              cr->fill();                              cr->fill();
534    
# Line 1008  bool DimRegionChooser::on_focus(Gtk::Dir Line 1126  bool DimRegionChooser::on_focus(Gtk::Dir
1126  void DimRegionChooser::split_dimension_zone() {      void DimRegionChooser::split_dimension_zone() {    
1127      printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);      printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1128      try {      try {
1129          region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);          if (!modifyallregions) {
1130                region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
1131            } else {
1132                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
1133                gig::dimension_def_t* pMaindimdef = region->GetDimensionDefinition(maindimtype);
1134                assert(pMaindimdef != NULL);
1135                // retain structure by value since the original region will be
1136                // modified in the loop below as well
1137                gig::dimension_def_t maindimdef = *pMaindimdef;
1138                std::vector<gig::Region*> ignoredAll;
1139                std::vector<gig::Region*> ignoredMinor;
1140                std::vector<gig::Region*> ignoredCritical;
1141                gig::Region* rgn = NULL;
1142                for (int key = 0; key < 128; ++key) {
1143                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
1144                    rgn = instr->GetRegion(key);
1145    
1146                    // ignore all regions which do not exactly match the dimension
1147                    // layout of the selected region where this operation was emitted
1148                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(maindimtype);
1149                    if (!dimdef) {
1150                        ignoredAll.push_back(rgn);
1151                        ignoredMinor.push_back(rgn);
1152                        continue;
1153                    }
1154                    if (dimdef->zones != maindimdef.zones) {
1155                        ignoredAll.push_back(rgn);
1156                        ignoredCritical.push_back(rgn);
1157                        continue;
1158                    }
1159    
1160                    rgn->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
1161                }
1162                if (!ignoredAll.empty()) {
1163                    Glib::ustring txt;
1164                    if (ignoredCritical.empty())
1165                        txt = ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type.");
1166                    else if (ignoredMinor.empty())
1167                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones!");
1168                    else
1169                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones (and ") +
1170                        ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type)!");
1171                    Gtk::MessageType type = (ignoredCritical.empty()) ? Gtk::MESSAGE_INFO : Gtk::MESSAGE_WARNING;
1172                    Gtk::MessageDialog msg(txt, false, type);
1173                    msg.run();
1174                }
1175            }
1176      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
1177          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1178          msg.run();          msg.run();
# Line 1023  void DimRegionChooser::split_dimension_z Line 1187  void DimRegionChooser::split_dimension_z
1187  void DimRegionChooser::delete_dimension_zone() {  void DimRegionChooser::delete_dimension_zone() {
1188      printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);      printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1189      try {      try {
1190          region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);          if (!modifyallregions) {
1191                region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
1192            } else {
1193                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
1194                gig::dimension_def_t* pMaindimdef = region->GetDimensionDefinition(maindimtype);
1195                assert(pMaindimdef != NULL);
1196                // retain structure by value since the original region will be
1197                // modified in the loop below as well
1198                gig::dimension_def_t maindimdef = *pMaindimdef;
1199                std::vector<gig::Region*> ignoredAll;
1200                std::vector<gig::Region*> ignoredMinor;
1201                std::vector<gig::Region*> ignoredCritical;
1202                gig::Region* rgn = NULL;
1203                for (int key = 0; key < 128; ++key) {
1204                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
1205                    rgn = instr->GetRegion(key);
1206    
1207                    // ignore all regions which do not exactly match the dimension
1208                    // layout of the selected region where this operation was emitted
1209                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(maindimtype);
1210                    if (!dimdef) {
1211                        ignoredAll.push_back(rgn);
1212                        ignoredMinor.push_back(rgn);
1213                        continue;
1214                    }
1215                    if (dimdef->zones != maindimdef.zones) {
1216                        ignoredAll.push_back(rgn);
1217                        ignoredCritical.push_back(rgn);
1218                        continue;
1219                    }
1220    
1221                    rgn->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
1222                }
1223                if (!ignoredAll.empty()) {
1224                    Glib::ustring txt;
1225                    if (ignoredCritical.empty())
1226                        txt = ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type.");
1227                    else if (ignoredMinor.empty())
1228                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones!");
1229                    else
1230                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones (and ") +
1231                              ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type)!");
1232                    Gtk::MessageType type = (ignoredCritical.empty()) ? Gtk::MESSAGE_INFO : Gtk::MESSAGE_WARNING;
1233                    Gtk::MessageDialog msg(txt, false, type);
1234                    msg.run();
1235                }
1236            }
1237      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
1238          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1239          msg.run();          msg.run();
# Line 1035  void DimRegionChooser::delete_dimension_ Line 1245  void DimRegionChooser::delete_dimension_
1245      refresh_all();      refresh_all();
1246  }  }
1247    
1248    // Cmd key on Mac, Ctrl key on all other OSs
1249    static const guint primaryKeyL =
1250        #if defined(__APPLE__)
1251        GDK_KEY_Meta_L;
1252        #else
1253        GDK_KEY_Control_L;
1254        #endif
1255    
1256    static const guint primaryKeyR =
1257        #if defined(__APPLE__)
1258        GDK_KEY_Meta_R;
1259        #else
1260        GDK_KEY_Control_R;
1261        #endif
1262    
1263  bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {  bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {
1264      //printf("key down\n");      //printf("key down 0x%x\n", key->keyval);
1265      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)
1266          multiSelectKeyDown = true;          multiSelectKeyDown = true;
1267        if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
1268            primaryKeyDown = true;
1269        if (key->keyval == GDK_KEY_Shift_L || key->keyval == GDK_KEY_Shift_R)
1270            shiftKeyDown = true;
1271    
1272        //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
1273        /*if (key->keyval == GDK_KEY_Left)
1274            select_prev_dimzone();
1275        if (key->keyval == GDK_KEY_Right)
1276            select_next_dimzone();
1277        if (key->keyval == GDK_KEY_Up)
1278            select_prev_dimension();
1279        if (key->keyval == GDK_KEY_Down)
1280            select_next_dimension();*/
1281      return false;      return false;
1282  }  }
1283    
1284  bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {  bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {
1285      //printf("key up\n");      //printf("key up 0x%x\n", key->keyval);
1286      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)
1287          multiSelectKeyDown = false;          multiSelectKeyDown = false;
1288        if (key->keyval == primaryKeyL || key->keyval == primaryKeyR)
1289            primaryKeyDown = false;
1290        if (key->keyval == GDK_KEY_Shift_L || key->keyval == GDK_KEY_Shift_R)
1291            shiftKeyDown = false;
1292    
1293        if (!has_focus()) return false;
1294    
1295        // avoid conflict with Ctrl+Left and Ctrl+Right accelerators on mainwindow
1296        // (which is supposed to switch between regions)
1297        if (primaryKeyDown) return false;
1298    
1299        // avoid conflict with Alt+Shift+Left and Alt+Shift+Right accelerators on
1300        // mainwindow
1301        if (shiftKeyDown) return false;
1302    
1303        if (key->keyval == GDK_KEY_Left)
1304            select_prev_dimzone();
1305        if (key->keyval == GDK_KEY_Right)
1306            select_next_dimzone();
1307        if (key->keyval == GDK_KEY_Up)
1308            select_prev_dimension();
1309        if (key->keyval == GDK_KEY_Down)
1310            select_next_dimension();
1311    
1312      return false;      return false;
1313  }  }
1314    
# Line 1066  void DimRegionChooser::resetSelectedZone Line 1329  void DimRegionChooser::resetSelectedZone
1329      gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];      gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];
1330    
1331      bool isValidZone;      bool isValidZone;
1332      this->maindimcase = caseOfDimRegion(dimrgn, &isValidZone);      this->maindimcase = dimensionCaseOf(dimrgn);
     if (!isValidZone) {  
         queue_draw(); // redraw required parts  
         return;  
     }  
1333    
1334      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();
1335           it != this->maindimcase.end(); ++it)           it != this->maindimcase.end(); ++it)
# Line 1101  bool DimRegionChooser::select_dimregion( Line 1360  bool DimRegionChooser::select_dimregion(
1360      return false; //.selection failed      return false; //.selection failed
1361  }  }
1362    
1363    void DimRegionChooser::select_next_dimzone(bool add) {
1364        select_dimzone_by_dir(+1, add);
1365    }
1366    
1367    void DimRegionChooser::select_prev_dimzone(bool add) {
1368        select_dimzone_by_dir(-1, add);
1369    }
1370    
1371    void DimRegionChooser::select_dimzone_by_dir(int dir, bool add) {
1372        if (!region) return;
1373        if (!region->Dimensions) return;
1374        if (focus_line < 0) focus_line = 0;
1375        if (focus_line >= region->Dimensions) focus_line = region->Dimensions - 1;
1376    
1377        maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1378        if (maindimtype == gig::dimension_none) {
1379            printf("maindimtype -> none\n");
1380            return;
1381        }
1382    
1383        if (maindimcase.empty()) {
1384            maindimcase = dimensionCaseOf(region->pDimensionRegions[maindimregno]);
1385            if (maindimcase.empty()) {
1386                printf("caseOfDimregion(%d) -> empty\n", maindimregno);
1387                return;
1388            }
1389        }
1390    
1391        int z = (dir > 0) ? maindimcase[maindimtype] + 1 : maindimcase[maindimtype] - 1;
1392        if (z < 0) z = 0;
1393        if (z >= region->pDimensionDefinitions[focus_line].zones)
1394            z = region->pDimensionDefinitions[focus_line].zones - 1;
1395    
1396        maindimcase[maindimtype] = z;
1397    
1398        ::gig::DimensionRegion* dr = dimensionRegionMatching(maindimcase, region);
1399        if (!dr) {
1400            printf("select_dimzone_by_dir(%d) -> !dr\n", dir);
1401            return;
1402        }
1403    
1404        maindimregno = getDimensionRegionIndex(dr);
1405    
1406        if (!add) {
1407            // reset selected dimregion zones
1408            dimzones.clear();
1409        }
1410        for (DimensionCase::const_iterator it = maindimcase.begin();
1411             it != maindimcase.end(); ++it)
1412        {
1413            dimzones[it->first].insert(it->second);
1414        }
1415    
1416        dimregion_selected();
1417    
1418        // disabled: would overwrite dimregno with wrong value
1419        //refresh_all();
1420        // so requesting just a raw repaint instead:
1421        queue_draw();
1422    }
1423    
1424    void DimRegionChooser::select_next_dimension() {
1425        if (!region) return;
1426        focus_line++;
1427        if (focus_line >= region->Dimensions)
1428            focus_line = region->Dimensions - 1;
1429        this->maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1430        queue_draw();
1431    }
1432    
1433    void DimRegionChooser::select_prev_dimension() {
1434        if (!region) return;
1435        focus_line--;
1436        if (focus_line < 0)
1437            focus_line = 0;
1438        this->maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1439        queue_draw();
1440    }
1441    
1442  gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {  gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {
1443      if (!region) return NULL;      if (!region) return NULL;
1444      return region->pDimensionRegions[maindimregno];      return region->pDimensionRegions[maindimregno];

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

  ViewVC Help
Powered by ViewVC