/[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 3123 by schoenebeck, Tue Apr 25 20:45:54 2017 UTC
# Line 29  Line 29 
29    
30  #include "global.h"  #include "global.h"
31    
32  // taken from gdk/gdkkeysyms.h  //TODO: this function and dimensionCaseOf() from global.h are duplicates, eliminate either one of them!
33  // (define on demand, to avoid unnecessary dev lib package build dependency)  static DimensionCase caseOfDimRegion(gig::DimensionRegion* dr, bool* isValidZone) {
34  #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;  
35      if (!dr) {      if (!dr) {
36          *isValidZone = false;          *isValidZone = false;
37          return dimCase;          return dimCase;
# Line 57  static std::map<gig::dimension_t,int> ca Line 49  static std::map<gig::dimension_t,int> ca
49      if (drIndex == 256) {      if (drIndex == 256) {
50          fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");          fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");
51          *isValidZone = false;          *isValidZone = false;
52          return std::map<gig::dimension_t,int>();          return DimensionCase();
53      }      }
54    
55      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 60  static std::map<gig::dimension_t,int> ca
60          // there are also DimensionRegion objects of unused zones, skip them          // there are also DimensionRegion objects of unused zones, skip them
61          if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {          if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {
62              *isValidZone = false;              *isValidZone = false;
63              return std::map<gig::dimension_t,int>();              return DimensionCase();
64          }          }
65      }      }
66    
# Line 84  DimRegionChooser::DimRegionChooser(Gtk:: Line 76  DimRegionChooser::DimRegionChooser(Gtk::
76      instrument = 0;      instrument = 0;
77      region = 0;      region = 0;
78      maindimregno = -1;      maindimregno = -1;
79        maindimtype = gig::dimension_none; // initialize with invalid dimension type
80      focus_line = 0;      focus_line = 0;
81      resize.active = false;      resize.active = false;
82      cursor_is_resize = false;      cursor_is_resize = false;
# Line 92  DimRegionChooser::DimRegionChooser(Gtk:: Line 85  DimRegionChooser::DimRegionChooser(Gtk::
85      modifybothchannels = modifyalldimregs = modifybothchannels = false;      modifybothchannels = modifyalldimregs = modifybothchannels = false;
86      set_can_focus();      set_can_focus();
87    
88        const Glib::ustring txtUseCheckBoxAllRegions =
89            _("Use checkbox 'all regions' to control whether this should apply to all regions.");
90    
91      actionGroup = Gtk::ActionGroup::create();      actionGroup = Gtk::ActionGroup::create();
92        actionSplitDimZone = Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone"), txtUseCheckBoxAllRegions);
93        actionSplitDimZone->set_tooltip(txtUseCheckBoxAllRegions); //FIXME: doesn't work? why???
94      actionGroup->add(      actionGroup->add(
95          Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone")),          actionSplitDimZone,
96          sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)          sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)
97      );      );
98        actionDeleteDimZone = Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone"), txtUseCheckBoxAllRegions);
99        actionDeleteDimZone->set_tooltip(txtUseCheckBoxAllRegions); //FIXME: doesn't work? why???
100      actionGroup->add(      actionGroup->add(
101          Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone")),          actionDeleteDimZone,
102          sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)          sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)
103      );      );
104    
# Line 153  void DimRegionChooser::setModifyAllDimen Line 153  void DimRegionChooser::setModifyAllDimen
153    
154  void DimRegionChooser::setModifyAllRegions(bool b) {  void DimRegionChooser::setModifyAllRegions(bool b) {
155      modifyallregions = b;      modifyallregions = b;
156    
157        actionDeleteDimZone->set_label(b ? _("Delete Dimension Zone [ALL REGIONS]") : _("Delete Dimension Zone"));
158        actionSplitDimZone->set_label(b ? _("Split Dimensions Zone [ALL REGIONS]") : _("Split Dimensions Zone"));
159  }  }
160    
161  #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 1008  bool DimRegionChooser::on_focus(Gtk::Dir Line 1011  bool DimRegionChooser::on_focus(Gtk::Dir
1011  void DimRegionChooser::split_dimension_zone() {      void DimRegionChooser::split_dimension_zone() {    
1012      printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);      printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1013      try {      try {
1014          region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);          if (!modifyallregions) {
1015                region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
1016            } else {
1017                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
1018                gig::dimension_def_t* pMaindimdef = region->GetDimensionDefinition(maindimtype);
1019                assert(pMaindimdef != NULL);
1020                // retain structure by value since the original region will be
1021                // modified in the loop below as well
1022                gig::dimension_def_t maindimdef = *pMaindimdef;
1023                std::vector<gig::Region*> ignoredAll;
1024                std::vector<gig::Region*> ignoredMinor;
1025                std::vector<gig::Region*> ignoredCritical;
1026                gig::Region* rgn = NULL;
1027                for (int key = 0; key < 128; ++key) {
1028                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
1029                    rgn = instr->GetRegion(key);
1030    
1031                    // ignore all regions which do not exactly match the dimension
1032                    // layout of the selected region where this operation was emitted
1033                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(maindimtype);
1034                    if (!dimdef) {
1035                        ignoredAll.push_back(rgn);
1036                        ignoredMinor.push_back(rgn);
1037                        continue;
1038                    }
1039                    if (dimdef->zones != maindimdef.zones) {
1040                        ignoredAll.push_back(rgn);
1041                        ignoredCritical.push_back(rgn);
1042                        continue;
1043                    }
1044    
1045                    rgn->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
1046                }
1047                if (!ignoredAll.empty()) {
1048                    Glib::ustring txt;
1049                    if (ignoredCritical.empty())
1050                        txt = ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type.");
1051                    else if (ignoredMinor.empty())
1052                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones!");
1053                    else
1054                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones (and ") +
1055                        ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type)!");
1056                    Gtk::MessageType type = (ignoredCritical.empty()) ? Gtk::MESSAGE_INFO : Gtk::MESSAGE_WARNING;
1057                    Gtk::MessageDialog msg(txt, false, type);
1058                    msg.run();
1059                }
1060            }
1061      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
1062          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1063          msg.run();          msg.run();
# Line 1023  void DimRegionChooser::split_dimension_z Line 1072  void DimRegionChooser::split_dimension_z
1072  void DimRegionChooser::delete_dimension_zone() {  void DimRegionChooser::delete_dimension_zone() {
1073      printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);      printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1074      try {      try {
1075          region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);          if (!modifyallregions) {
1076                region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
1077            } else {
1078                gig::Instrument* instr = (gig::Instrument*)region->GetParent();
1079                gig::dimension_def_t* pMaindimdef = region->GetDimensionDefinition(maindimtype);
1080                assert(pMaindimdef != NULL);
1081                // retain structure by value since the original region will be
1082                // modified in the loop below as well
1083                gig::dimension_def_t maindimdef = *pMaindimdef;
1084                std::vector<gig::Region*> ignoredAll;
1085                std::vector<gig::Region*> ignoredMinor;
1086                std::vector<gig::Region*> ignoredCritical;
1087                gig::Region* rgn = NULL;
1088                for (int key = 0; key < 128; ++key) {
1089                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
1090                    rgn = instr->GetRegion(key);
1091    
1092                    // ignore all regions which do not exactly match the dimension
1093                    // layout of the selected region where this operation was emitted
1094                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(maindimtype);
1095                    if (!dimdef) {
1096                        ignoredAll.push_back(rgn);
1097                        ignoredMinor.push_back(rgn);
1098                        continue;
1099                    }
1100                    if (dimdef->zones != maindimdef.zones) {
1101                        ignoredAll.push_back(rgn);
1102                        ignoredCritical.push_back(rgn);
1103                        continue;
1104                    }
1105    
1106                    rgn->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
1107                }
1108                if (!ignoredAll.empty()) {
1109                    Glib::ustring txt;
1110                    if (ignoredCritical.empty())
1111                        txt = ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type.");
1112                    else if (ignoredMinor.empty())
1113                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones!");
1114                    else
1115                        txt = ToString(ignoredCritical.size()) + _(" regions have been ignored due to different amount of dimension zones (and ") +
1116                              ToString(ignoredMinor.size()) + _(" regions have been ignored since they don't have that dimension type)!");
1117                    Gtk::MessageType type = (ignoredCritical.empty()) ? Gtk::MESSAGE_INFO : Gtk::MESSAGE_WARNING;
1118                    Gtk::MessageDialog msg(txt, false, type);
1119                    msg.run();
1120                }
1121            }
1122      } catch (RIFF::Exception e) {      } catch (RIFF::Exception e) {
1123          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1124          msg.run();          msg.run();
# Line 1036  void DimRegionChooser::delete_dimension_ Line 1131  void DimRegionChooser::delete_dimension_
1131  }  }
1132    
1133  bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {  bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {
1134      //printf("key down\n");      //printf("key down 0x%x\n", key->keyval);
1135      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)
1136          multiSelectKeyDown = true;          multiSelectKeyDown = true;
1137        //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
1138        /*if (key->keyval == GDK_KEY_Left)
1139            select_prev_dimzone();
1140        if (key->keyval == GDK_KEY_Right)
1141            select_next_dimzone();
1142        if (key->keyval == GDK_KEY_Up)
1143            select_prev_dimension();
1144        if (key->keyval == GDK_KEY_Down)
1145            select_next_dimension();*/
1146      return false;      return false;
1147  }  }
1148    
1149  bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {  bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {
1150      //printf("key up\n");      //printf("key up 0x%x\n", key->keyval);
1151      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)
1152          multiSelectKeyDown = false;          multiSelectKeyDown = false;
1153    
1154        if (!has_focus()) return false;
1155    
1156        if (key->keyval == GDK_KEY_Left)
1157            select_prev_dimzone();
1158        if (key->keyval == GDK_KEY_Right)
1159            select_next_dimzone();
1160        if (key->keyval == GDK_KEY_Up)
1161            select_prev_dimension();
1162        if (key->keyval == GDK_KEY_Down)
1163            select_next_dimension();
1164    
1165      return false;      return false;
1166  }  }
1167    
# Line 1066  void DimRegionChooser::resetSelectedZone Line 1182  void DimRegionChooser::resetSelectedZone
1182      gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];      gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];
1183    
1184      bool isValidZone;      bool isValidZone;
1185      this->maindimcase = caseOfDimRegion(dimrgn, &isValidZone);      this->maindimcase = dimensionCaseOf(dimrgn);
     if (!isValidZone) {  
         queue_draw(); // redraw required parts  
         return;  
     }  
1186    
1187      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();
1188           it != this->maindimcase.end(); ++it)           it != this->maindimcase.end(); ++it)
# Line 1101  bool DimRegionChooser::select_dimregion( Line 1213  bool DimRegionChooser::select_dimregion(
1213      return false; //.selection failed      return false; //.selection failed
1214  }  }
1215    
1216    void DimRegionChooser::select_next_dimzone() {
1217        select_dimzone_by_dir(+1);
1218    }
1219    
1220    void DimRegionChooser::select_prev_dimzone() {
1221        select_dimzone_by_dir(-1);
1222    }
1223    
1224    void DimRegionChooser::select_dimzone_by_dir(int dir) {
1225        if (!region) return;
1226        if (!region->Dimensions) return;
1227        if (focus_line < 0) focus_line = 0;
1228        if (focus_line >= region->Dimensions) focus_line = region->Dimensions - 1;
1229    
1230        maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1231        if (maindimtype == gig::dimension_none) {
1232            printf("maindimtype -> none\n");
1233            return;
1234        }
1235    
1236        if (maindimcase.empty()) {
1237            maindimcase = dimensionCaseOf(region->pDimensionRegions[maindimregno]);
1238            if (maindimcase.empty()) {
1239                printf("caseOfDimregion(%d) -> empty\n", maindimregno);
1240                return;
1241            }
1242        }
1243    
1244        int z = (dir > 0) ? maindimcase[maindimtype] + 1 : maindimcase[maindimtype] - 1;
1245        if (z < 0) z = 0;
1246        if (z >= region->pDimensionDefinitions[focus_line].zones)
1247            z = region->pDimensionDefinitions[focus_line].zones - 1;
1248    
1249        maindimcase[maindimtype] = z;
1250    
1251        ::gig::DimensionRegion* dr = dimensionRegionMatching(maindimcase, region);
1252        if (!dr) {
1253            printf("select_dimzone_by_dir(%d) -> !dr\n", dir);
1254            return;
1255        }
1256    
1257        maindimregno = getDimensionRegionIndex(dr);
1258    
1259        // reset selected dimregion zones
1260        dimzones.clear();
1261        for (DimensionCase::const_iterator it = maindimcase.begin();
1262             it != maindimcase.end(); ++it)
1263        {
1264            dimzones[it->first].insert(it->second);
1265        }
1266    
1267        dimregion_selected();
1268    
1269        // disabled: would overwrite dimregno with wrong value
1270        //refresh_all();
1271        // so requesting just a raw repaint instead:
1272        queue_draw();
1273    }
1274    
1275    void DimRegionChooser::select_next_dimension() {
1276        if (!region) return;
1277        focus_line++;
1278        if (focus_line >= region->Dimensions)
1279            focus_line = region->Dimensions - 1;
1280        this->maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1281        queue_draw();
1282    }
1283    
1284    void DimRegionChooser::select_prev_dimension() {
1285        if (!region) return;
1286        focus_line--;
1287        if (focus_line < 0)
1288            focus_line = 0;
1289        this->maindimtype = region->pDimensionDefinitions[focus_line].dimension;
1290        queue_draw();
1291    }
1292    
1293  gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {  gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {
1294      if (!region) return NULL;      if (!region) return NULL;
1295      return region->pDimensionRegions[maindimregno];      return region->pDimensionRegions[maindimregno];

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

  ViewVC Help
Powered by ViewVC