/[svn]/gigedit/trunk/src/gigedit/dimregionchooser.cpp
ViewVC logotype

Diff of /gigedit/trunk/src/gigedit/dimregionchooser.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2626 by schoenebeck, Thu Jun 12 15:12:00 2014 UTC revision 3105 by schoenebeck, Fri Feb 10 18:40:26 2017 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2014 Andreas Persson   * Copyright (C) 2006-2017 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 17  Line 17 
17   * 02110-1301 USA.   * 02110-1301 USA.
18   */   */
19    
20    #include <gtkmm/box.h>
21  #include "dimregionchooser.h"  #include "dimregionchooser.h"
22  #include <cairomm/context.h>  #include <cairomm/context.h>
23  #include <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
24  #include <gdkmm/general.h>  #include <gdkmm/general.h>
25  #include <glibmm/stringutils.h>  #include <glibmm/stringutils.h>
 #include <gtkmm/stock.h>  
26  #include <glibmm/ustring.h>  #include <glibmm/ustring.h>
27  #include <gtkmm/messagedialog.h>  #include <gtkmm/messagedialog.h>
28    #include <assert.h>
29    
30  #include "global.h"  #include "global.h"
31    
# Line 86  DimRegionChooser::DimRegionChooser(Gtk:: Line 87  DimRegionChooser::DimRegionChooser(Gtk::
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;      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();      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(      actionGroup->add(
102          Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone")),          actionSplitDimZone,
103          sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)          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(      actionGroup->add(
108          Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone")),          actionDeleteDimZone,
109          sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)          sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)
110      );      );
111    
# Line 141  DimRegionChooser::~DimRegionChooser() Line 150  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 273  bool DimRegionChooser::on_draw(const Cai Line 297  bool DimRegionChooser::on_draw(const Cai
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 318  bool DimRegionChooser::on_draw(const Cai Line 342  bool DimRegionChooser::on_draw(const Cai
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;                      int prevX = label_width;
345                      int prevUpperLimit = 0;                      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                          // draw dimension zone's borders for custom splits
# Line 346  bool DimRegionChooser::on_draw(const Cai Line 370  bool DimRegionChooser::on_draw(const Cai
370                          // as numeric value to the user                          // as numeric value to the user
371                          {                          {
372                              Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                              Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
373                              layout->set_text(Glib::Ascii::dtostr(prevUpperLimit));                              layout->set_text(Glib::Ascii::dtostr(prevUpperLimit+1));
374                              Gdk::Cairo::set_source_rgba(cr, black);                              Gdk::Cairo::set_source_rgba(cr, black);
                             Pango::Rectangle rect = layout->get_logical_extents();  
375                              // get the text dimensions                              // get the text dimensions
376                              int text_width, text_height;                              int text_width, text_height;
377                              layout->get_pixel_size(text_width, text_height);                              layout->get_pixel_size(text_width, text_height);
378                              // move text to the left end of the dimension zone                              // move text to the left end of the dimension zone
379                              cr->move_to(prevX + 3, y + 1);                              cr->move_to(prevX + 3, y + (h - text_height) / 2);
380  #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
381                              pango_cairo_show_layout(cr->cobj(), layout->gobj());                              pango_cairo_show_layout(cr->cobj(), layout->gobj());
382  #else  #else
# Line 366  bool DimRegionChooser::on_draw(const Cai Line 389  bool DimRegionChooser::on_draw(const Cai
389                              Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                              Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
390                              layout->set_text(Glib::Ascii::dtostr(upperLimit));                              layout->set_text(Glib::Ascii::dtostr(upperLimit));
391                              Gdk::Cairo::set_source_rgba(cr, black);                              Gdk::Cairo::set_source_rgba(cr, black);
                             Pango::Rectangle rect = layout->get_logical_extents();  
392                              // get the text dimensions                              // get the text dimensions
393                              int text_width, text_height;                              int text_width, text_height;
394                              layout->get_pixel_size(text_width, text_height);                              layout->get_pixel_size(text_width, text_height);
395                              // move text to the left end of the dimension zone                              // move text to the left end of the dimension zone
396                              cr->move_to(x - 3 - text_width, y + 1);                              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  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
398                              pango_cairo_show_layout(cr->cobj(), layout->gobj());                              pango_cairo_show_layout(cr->cobj(), layout->gobj());
399  #else  #else
# Line 408  bool DimRegionChooser::on_draw(const Cai Line 430  bool DimRegionChooser::on_draw(const Cai
430                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
431                                  layout->set_text(Glib::Ascii::dtostr((j-1) * 128/nbZones));                                  layout->set_text(Glib::Ascii::dtostr((j-1) * 128/nbZones));
432                                  Gdk::Cairo::set_source_rgba(cr, black);                                  Gdk::Cairo::set_source_rgba(cr, black);
                                 Pango::Rectangle rect = layout->get_logical_extents();  
433                                  // get the text dimensions                                  // get the text dimensions
434                                  int text_width, text_height;                                  int text_width, text_height;
435                                  layout->get_pixel_size(text_width, text_height);                                  layout->get_pixel_size(text_width, text_height);
436                                  // move text to the left end of the dimension zone                                  // move text to the left end of the dimension zone
437                                  cr->move_to(prevX + 3, y + 1);                                  cr->move_to(prevX + 3, y + (h - text_height) / 2);
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
# Line 426  bool DimRegionChooser::on_draw(const Cai Line 447  bool DimRegionChooser::on_draw(const Cai
447                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
448                                  layout->set_text(Glib::Ascii::dtostr(j * 128/nbZones - 1));                                  layout->set_text(Glib::Ascii::dtostr(j * 128/nbZones - 1));
449                                  Gdk::Cairo::set_source_rgba(cr, black);                                  Gdk::Cairo::set_source_rgba(cr, black);
                                 Pango::Rectangle rect = layout->get_logical_extents();  
450                                  // get the text dimensions                                  // get the text dimensions
451                                  int text_width, text_height;                                  int text_width, text_height;
452                                  layout->get_pixel_size(text_width, text_height);                                  layout->get_pixel_size(text_width, text_height);
453                                  // move text to the left end of the dimension zone                                  // move text to the left end of the dimension zone
454                                  cr->move_to(x - 3 - text_width, y + 1);                                  cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
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
# Line 469  void DimRegionChooser::set_region(gig::R Line 489  void DimRegionChooser::set_region(gig::R
489          }          }
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();
# Line 511  void DimRegionChooser::get_dimregions(co Line 531  void DimRegionChooser::get_dimregions(co
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 = maindimregno & mask; // mask away this dimension          int c = maindimregno & mask; // mask away this dimension
# Line 542  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 565  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 581  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 809  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    
# Line 850  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 883  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() {      void DimRegionChooser::split_dimension_zone() {    
1019      printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);      printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1020      try {      try {
1021          region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);          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) {      } catch (RIFF::Exception e) {
1069          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1070          msg.run();          msg.run();
# Line 909  void DimRegionChooser::split_dimension_z Line 1079  void DimRegionChooser::split_dimension_z
1079  void DimRegionChooser::delete_dimension_zone() {  void DimRegionChooser::delete_dimension_zone() {
1080      printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);      printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
1081      try {      try {
1082          region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);          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) {      } catch (RIFF::Exception e) {
1130          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);          Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
1131          msg.run();          msg.run();
# Line 925  bool DimRegionChooser::onKeyPressed(GdkE Line 1141  bool DimRegionChooser::onKeyPressed(GdkE
1141      //printf("key down\n");      //printf("key down\n");
1142      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)
1143          multiSelectKeyDown = true;          multiSelectKeyDown = true;
1144        return false;
1145  }  }
1146    
1147  bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {  bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {
1148      //printf("key up\n");      //printf("key up\n");
1149      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)
1150          multiSelectKeyDown = false;          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 {  gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {

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

  ViewVC Help
Powered by ViewVC