/[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 2169 by persson, Sun Mar 6 07:51:04 2011 UTC revision 2841 by persson, Sun Aug 30 10:00:49 2015 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2011 Andreas Persson   * Copyright (C) 2006-2015 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 21  Line 21 
21  #include <cairomm/context.h>  #include <cairomm/context.h>
22  #include <gdkmm/cursor.h>  #include <gdkmm/cursor.h>
23  #include <gdkmm/general.h>  #include <gdkmm/general.h>
24    #include <glibmm/stringutils.h>
25    #include <gtkmm/stock.h>
26    #include <glibmm/ustring.h>
27    #include <gtkmm/messagedialog.h>
28    
29  #include "global.h"  #include "global.h"
30    
31  DimRegionChooser::DimRegionChooser() :  // taken from gdk/gdkkeysyms.h
32    // (define on demand, to avoid unnecessary dev lib package build dependency)
33    #ifndef GDK_KEY_Control_L
34    # define GDK_KEY_Control_L 0xffe3
35    #endif
36    #ifndef GDK_KEY_Control_R
37    # define GDK_KEY_Control_R 0xffe4
38    #endif
39    
40    static std::map<gig::dimension_t,int> caseOfDimRegion(gig::DimensionRegion* dr, bool* isValidZone) {
41        std::map<gig::dimension_t,int> dimCase;
42        if (!dr) {
43            *isValidZone = false;
44            return dimCase;
45        }
46    
47        gig::Region* rgn = (gig::Region*) dr->GetParent();
48    
49        // find the dimension region index of the passed dimension region
50        int drIndex;
51        for (drIndex = 0; drIndex < 256; ++drIndex)
52            if (rgn->pDimensionRegions[drIndex] == dr)
53                break;
54    
55        // not found in region, something's horribly wrong
56        if (drIndex == 256) {
57            fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");
58            *isValidZone = false;
59            return std::map<gig::dimension_t,int>();
60        }
61    
62        for (int d = 0, baseBits = 0; d < rgn->Dimensions; ++d) {
63            const int bits = rgn->pDimensionDefinitions[d].bits;
64            dimCase[rgn->pDimensionDefinitions[d].dimension] =
65                (drIndex >> baseBits) & ((1 << bits) - 1);
66            baseBits += bits;
67            // there are also DimensionRegion objects of unused zones, skip them
68            if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {
69                *isValidZone = false;
70                return std::map<gig::dimension_t,int>();
71            }
72        }
73    
74        *isValidZone = true;
75        return dimCase;
76    }
77    
78    DimRegionChooser::DimRegionChooser(Gtk::Window& window) :
79      red("#8070ff"),      red("#8070ff"),
80      black("black"),      black("black"),
81      white("white")      white("white")
82  {  {
83      instrument = 0;      instrument = 0;
84      region = 0;      region = 0;
85      dimregno = -1;      maindimregno = -1;
86      focus_line = 0;      focus_line = 0;
87      resize.active = false;      resize.active = false;
88      cursor_is_resize = false;      cursor_is_resize = false;
89      h = 20;      h = 24;
90        multiSelectKeyDown = false;
91      set_can_focus();      set_can_focus();
92    
93        actionGroup = Gtk::ActionGroup::create();
94        actionGroup->add(
95            Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone")),
96            sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)
97        );
98        actionGroup->add(
99            Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone")),
100            sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)
101        );
102    
103        uiManager = Gtk::UIManager::create();
104        uiManager->insert_action_group(actionGroup);
105        Glib::ustring ui_info =
106            "<ui>"
107            "  <popup name='PopupMenuInsideDimRegion'>"
108            "    <menuitem action='SplitDimZone'/>"
109            "    <menuitem action='DeleteDimZone'/>"
110            "  </popup>"
111    //         "  <popup name='PopupMenuOutsideDimRegion'>"
112    //         "    <menuitem action='Add'/>"
113    //         "  </popup>"
114            "</ui>";
115        uiManager->add_ui_from_string(ui_info);
116    
117        popup_menu_inside_dimregion = dynamic_cast<Gtk::Menu*>(
118            uiManager->get_widget("/PopupMenuInsideDimRegion"));
119    //     popup_menu_outside_dimregion = dynamic_cast<Gtk::Menu*>(
120    //         uiManager->get_widget("/PopupMenuOutsideDimRegion"));
121    
122      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |
123                 Gdk::POINTER_MOTION_HINT_MASK);                 Gdk::POINTER_MOTION_HINT_MASK);
124    
125      for (int i = 0 ; i < 256 ; i++) dimvalue[i] = 0;      labels_changed = true;
126    
127        set_tooltip_text(_(
128            "Right click here for options on altering dimension zones. Press and "
129            "hold CTRL key for selecting multiple dimension zones simultaniously."
130        ));
131        
132        window.signal_key_press_event().connect(
133            sigc::mem_fun(*this, &DimRegionChooser::onKeyPressed)
134        );
135        window.signal_key_release_event().connect(
136            sigc::mem_fun(*this, &DimRegionChooser::onKeyReleased)
137        );
138  }  }
139    
140  DimRegionChooser::~DimRegionChooser()  DimRegionChooser::~DimRegionChooser()
# Line 50  DimRegionChooser::~DimRegionChooser() Line 144  DimRegionChooser::~DimRegionChooser()
144  #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
145  bool DimRegionChooser::on_expose_event(GdkEventExpose* e)  bool DimRegionChooser::on_expose_event(GdkEventExpose* e)
146  {  {
147      return on_draw(get_window()->create_cairo_context());      double clipx1 = e->area.x;
148  }      double clipx2 = e->area.x + e->area.width;
149  #endif      double clipy1 = e->area.y;
150        double clipy2 = e->area.y + e->area.height;
151    
152        const Cairo::RefPtr<Cairo::Context>& cr =
153            get_window()->create_cairo_context();
154    #else
155  bool DimRegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)  bool DimRegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
156  {  {
157        double clipx1, clipx2, clipy1, clipy2;
158        cr->get_clip_extents(clipx1, clipy1, clipx2, clipy2);
159    #endif
160    
161      if (!region) return true;      if (!region) return true;
162    
163      // This is where we draw on the window      // This is where we draw on the window
# Line 65  bool DimRegionChooser::on_draw(const Cai Line 167  bool DimRegionChooser::on_draw(const Cai
167      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
168      cr->set_line_width(1);      cr->set_line_width(1);
169    
     // draw labels on the left (reflecting the dimension type)  
170      int y = 0;      int y = 0;
171      double maxwidth = 0;      if (labels_changed || label_width - 10 > clipx1) {
172      for (int i = 0 ; i < region->Dimensions ; i++) {          // draw labels on the left (reflecting the dimension type)
173          int nbZones = region->pDimensionDefinitions[i].zones;          double maxwidth = 0;
174          if (nbZones) {          for (int i = 0 ; i < region->Dimensions ; i++) {
175              const char* dstr;              int nbZones = region->pDimensionDefinitions[i].zones;
176              char dstrbuf[10];              if (nbZones) {
177              switch (region->pDimensionDefinitions[i].dimension) {                  const char* dstr;
178              case gig::dimension_none: dstr=_("none"); break;                  char dstrbuf[10];
179              case gig::dimension_samplechannel: dstr=_("samplechannel"); break;                  switch (region->pDimensionDefinitions[i].dimension) {
180              case gig::dimension_layer: dstr=_("layer"); break;                  case gig::dimension_none: dstr=_("none"); break;
181              case gig::dimension_velocity: dstr=_("velocity"); break;                  case gig::dimension_samplechannel: dstr=_("samplechannel");
182              case gig::dimension_channelaftertouch: dstr=_("channelaftertouch"); break;                      break;
183              case gig::dimension_releasetrigger: dstr=_("releasetrigger"); break;                  case gig::dimension_layer: dstr=_("layer"); break;
184              case gig::dimension_keyboard: dstr=_("keyswitching"); break;                  case gig::dimension_velocity: dstr=_("velocity"); break;
185              case gig::dimension_roundrobin: dstr=_("roundrobin"); break;                  case gig::dimension_channelaftertouch:
186              case gig::dimension_random: dstr=_("random"); break;                      dstr=_("channelaftertouch"); break;
187              case gig::dimension_smartmidi: dstr=_("smartmidi"); break;                  case gig::dimension_releasetrigger:
188              case gig::dimension_roundrobinkeyboard: dstr=_("roundrobinkeyboard"); break;                      dstr=_("releasetrigger"); break;
189              case gig::dimension_modwheel: dstr=_("modwheel"); break;                  case gig::dimension_keyboard: dstr=_("keyswitching"); break;
190              case gig::dimension_breath: dstr=_("breath"); break;                  case gig::dimension_roundrobin: dstr=_("roundrobin"); break;
191              case gig::dimension_foot: dstr=_("foot"); break;                  case gig::dimension_random: dstr=_("random"); break;
192              case gig::dimension_portamentotime: dstr=_("portamentotime"); break;                  case gig::dimension_smartmidi: dstr=_("smartmidi"); break;
193              case gig::dimension_effect1: dstr=_("effect1"); break;                  case gig::dimension_roundrobinkeyboard:
194              case gig::dimension_effect2: dstr=_("effect2"); break;                      dstr=_("roundrobinkeyboard"); break;
195              case gig::dimension_genpurpose1: dstr=_("genpurpose1"); break;                  case gig::dimension_modwheel: dstr=_("modwheel"); break;
196              case gig::dimension_genpurpose2: dstr=_("genpurpose2"); break;                  case gig::dimension_breath: dstr=_("breath"); break;
197              case gig::dimension_genpurpose3: dstr=_("genpurpose3"); break;                  case gig::dimension_foot: dstr=_("foot"); break;
198              case gig::dimension_genpurpose4: dstr=_("genpurpose4"); break;                  case gig::dimension_portamentotime:
199              case gig::dimension_sustainpedal: dstr=_("sustainpedal"); break;                      dstr=_("portamentotime"); break;
200              case gig::dimension_portamento: dstr=_("portamento"); break;                  case gig::dimension_effect1: dstr=_("effect1"); break;
201              case gig::dimension_sostenutopedal: dstr=_("sostenutopedal"); break;                  case gig::dimension_effect2: dstr=_("effect2"); break;
202              case gig::dimension_softpedal: dstr=_("softpedal"); break;                  case gig::dimension_genpurpose1: dstr=_("genpurpose1"); break;
203              case gig::dimension_genpurpose5: dstr=_("genpurpose5"); break;                  case gig::dimension_genpurpose2: dstr=_("genpurpose2"); break;
204              case gig::dimension_genpurpose6: dstr=_("genpurpose6"); break;                  case gig::dimension_genpurpose3: dstr=_("genpurpose3"); break;
205              case gig::dimension_genpurpose7: dstr=_("genpurpose7"); break;                  case gig::dimension_genpurpose4: dstr=_("genpurpose4"); break;
206              case gig::dimension_genpurpose8: dstr=_("genpurpose8"); break;                  case gig::dimension_sustainpedal:
207              case gig::dimension_effect1depth: dstr=_("effect1depth"); break;                      dstr=_("sustainpedal"); break;
208              case gig::dimension_effect2depth: dstr=_("effect2depth"); break;                  case gig::dimension_portamento: dstr=_("portamento"); break;
209              case gig::dimension_effect3depth: dstr=_("effect3depth"); break;                  case gig::dimension_sostenutopedal:
210              case gig::dimension_effect4depth: dstr=_("effect4depth"); break;                      dstr=_("sostenutopedal"); break;
211              case gig::dimension_effect5depth: dstr=_("effect5depth"); break;                  case gig::dimension_softpedal: dstr=_("softpedal"); break;
212              default:                  case gig::dimension_genpurpose5: dstr=_("genpurpose5"); break;
213                  sprintf(dstrbuf, "%d",                  case gig::dimension_genpurpose6: dstr=_("genpurpose6"); break;
214                          region->pDimensionDefinitions[i].dimension);                  case gig::dimension_genpurpose7: dstr=_("genpurpose7"); break;
215                  dstr = dstrbuf;                  case gig::dimension_genpurpose8: dstr=_("genpurpose8"); break;
216                  break;                  case gig::dimension_effect1depth:
217              }                      dstr=_("effect1depth"); break;
218              layout->set_text(dstr);                  case gig::dimension_effect2depth:
219                        dstr=_("effect2depth"); break;
220              Pango::Rectangle rectangle = layout->get_logical_extents();                  case gig::dimension_effect3depth:
221              double text_w = double(rectangle.get_width()) / Pango::SCALE;                      dstr=_("effect3depth"); break;
222              if (text_w > maxwidth) maxwidth = text_w;                  case gig::dimension_effect4depth:
223              double text_h = double(rectangle.get_height()) / Pango::SCALE;                      dstr=_("effect4depth"); break;
224                    case gig::dimension_effect5depth:
225                        dstr=_("effect5depth"); break;
226                    default:
227                        sprintf(dstrbuf, "%d",
228                                region->pDimensionDefinitions[i].dimension);
229                        dstr = dstrbuf;
230                        break;
231                    }
232                    layout->set_text(dstr);
233    
234                    Pango::Rectangle rectangle = layout->get_logical_extents();
235                    double text_w = double(rectangle.get_width()) / Pango::SCALE;
236                    if (text_w > maxwidth) maxwidth = text_w;
237    
238                    if (y + h > clipy1 && y < clipy2 && text_w >= clipx1) {
239                        double text_h = double(rectangle.get_height()) /
240                            Pango::SCALE;
241  #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
242              const Gdk::Color fg = get_style()->get_fg(get_state());                      const Gdk::Color fg = get_style()->get_fg(get_state());
243  #else  #else
244              const Gdk::RGBA fg = get_style_context()->get_color(get_state_flags());                      const Gdk::RGBA fg =
245                            get_style_context()->get_color(get_state_flags());
246  #endif  #endif
247              Gdk::Cairo::set_source_rgba(cr, fg);                      Gdk::Cairo::set_source_rgba(cr, fg);
248              cr->move_to(4, int(y + (h - text_h) / 2 + 0.5));                      cr->move_to(4, int(y + (h - text_h) / 2 + 0.5));
249  #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
250              pango_cairo_show_layout(cr->cobj(), layout->gobj());                      pango_cairo_show_layout(cr->cobj(), layout->gobj());
251  #else  #else
252              layout->show_in_cairo_context(cr);                      layout->show_in_cairo_context(cr);
253  #endif  #endif
254                    }
255                }
256                y += h;
257          }          }
258          y += h;          label_width = int(maxwidth + 10);
259            labels_changed = false;
260      }      }
261        if (label_width >= clipx2) return true;
262    
263      // draw dimensions' zones areas      // draw dimensions' zones areas
264      y = 0;      y = 0;
265      int bitpos = 0;      int bitpos = 0;
     label_width = int(maxwidth + 10);  
266      for (int i = 0 ; i < region->Dimensions ; i++) {      for (int i = 0 ; i < region->Dimensions ; i++) {
267          int nbZones = region->pDimensionDefinitions[i].zones;          int nbZones = region->pDimensionDefinitions[i].zones;
268          if (nbZones) {          if (nbZones) {
269              // draw focus rectangle around dimension's label and zones              const gig::dimension_t dimension = region->pDimensionDefinitions[i].dimension;
270              if (has_focus() && focus_line == i) {  
271                if (y >= clipy2) break;
272                if (y + h > clipy1) {
273                    // draw focus rectangle around dimension's label and zones
274                    if (has_focus() && focus_line == i) {
275  #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
276                  Gdk::Rectangle farea(0, y, 150, 20);                      Gdk::Rectangle farea(0, y, 150, h);
277                  get_style()->paint_focus(get_window(), get_state(), farea, *this, "",                      get_style()->paint_focus(get_window(), get_state(), farea,
278                                           0, y, label_width, 20);                                               *this, "",
279  #else                                               0, y, label_width, h);
280                  get_style_context()->render_focus(cr, 0, y, label_width, 20);  #else
281                        get_style_context()->render_focus(cr,
282                                                          0, y, label_width, h);
283  #endif  #endif
284              }                  }
285    
286              // draw top and bottom lines of dimension's zones                  // draw top and bottom lines of dimension's zones
287              Gdk::Cairo::set_source_rgba(cr, black);                  Gdk::Cairo::set_source_rgba(cr, black);
288              cr->move_to(label_width, y + 0.5);                  cr->move_to(label_width, y + 0.5);
289              cr->line_to(w, y + 0.5);                  cr->line_to(w, y + 0.5);
290              cr->move_to(w, y + h - 0.5);                  cr->move_to(w, y + h - 0.5);
291              cr->line_to(label_width, y + h - 0.5);                  cr->line_to(label_width, y + h - 0.5);
292              cr->stroke();                  cr->stroke();
293    
294              // erase whole dimension's zones area                  // erase whole dimension's zones area
295              Gdk::Cairo::set_source_rgba(cr, white);                  Gdk::Cairo::set_source_rgba(cr, white);
296              cr->rectangle(label_width + 1, y + 1, (w - label_width - 2), h - 2);                  cr->rectangle(label_width + 1, y + 1,
297              cr->fill();                                (w - label_width - 2), h - 2);
298                    cr->fill();
             int c = 0;  
             if (dimregno >= 0) {  
                 int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);  
                 c = dimregno & mask; // mask away this dimension  
             }  
             bool customsplits =  
                 ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&  
                  region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||  
                 (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&  
                  region->pDimensionRegions[c]->VelocityUpperLimit));  
299    
300              // draw dimension's zone borders                  int c = 0;
301              Gdk::Cairo::set_source_rgba(cr, black);                  if (maindimregno >= 0) {
302              if (customsplits) {                      int mask =
303                  cr->move_to(label_width + 0.5, y + 1);                          ~(((1 << region->pDimensionDefinitions[i].bits) - 1) <<
304                  cr->line_to(label_width + 0.5, y + h - 1);                            bitpos);
305                        c = maindimregno & mask; // mask away this dimension
306                    }
307                    bool customsplits =
308                        ((region->pDimensionDefinitions[i].split_type ==
309                          gig::split_type_normal &&
310                          region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||
311                         (region->pDimensionDefinitions[i].dimension ==
312                          gig::dimension_velocity &&
313                          region->pDimensionRegions[c]->VelocityUpperLimit));
314    
315                  for (int j = 0 ; j < nbZones ; j++) {                  // draw dimension zones
316                      gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];                  Gdk::Cairo::set_source_rgba(cr, black);
                     int upperLimit = d->DimensionUpperLimits[i];  
                     if (!upperLimit) upperLimit = d->VelocityUpperLimit;  
                     int v = upperLimit + 1;  
                     int x = int((w - label_width - 1) * v / 128.0 + 0.5);  
                     cr->move_to(label_width + x + 0.5, y + 1);  
                     cr->line_to(label_width + x + 0.5, y + h - 1);  
                 }  
             } else {  
                 for (int j = 0 ; j <= nbZones ; j++) {  
                     int x = int((w - label_width - 1) * j / double(nbZones) + 0.5);  
                     cr->move_to(label_width + x + 0.5, y + 1);  
                     cr->line_to(label_width + x + 0.5, y + h - 1);  
                 }  
             }  
             cr->stroke();  
   
             // draw fill for currently selected zone  
             if (dimregno >= 0) {  
                 Gdk::Cairo::set_source_rgba(cr, red);  
                 int dr = (dimregno >> bitpos) & ((1 << region->pDimensionDefinitions[i].bits) - 1);  
317                  if (customsplits) {                  if (customsplits) {
318                      int x1 = 0;                      cr->move_to(label_width + 0.5, y + 1);
319                        cr->line_to(label_width + 0.5, y + h - 1);
320                        int prevX = label_width;
321                        int prevUpperLimit = -1;
322    
323                      for (int j = 0 ; j < nbZones ; j++) {                      for (int j = 0 ; j < nbZones ; j++) {
324                          gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];                          // draw dimension zone's borders for custom splits
325                            gig::DimensionRegion* d =
326                                region->pDimensionRegions[c + (j << bitpos)];
327                          int upperLimit = d->DimensionUpperLimits[i];                          int upperLimit = d->DimensionUpperLimits[i];
328                          if (!upperLimit) upperLimit = d->VelocityUpperLimit;                          if (!upperLimit) upperLimit = d->VelocityUpperLimit;
329                          int v = upperLimit + 1;                          int v = upperLimit + 1;
330                          int x2 = int((w - label_width - 1) * v / 128.0 + 0.5);                          int x = int((w - label_width - 1) * v / 128.0 + 0.5) +
331                          if (j == dr && x1 < x2) {                              label_width;
332                              cr->rectangle(label_width + x1 + 1, y + 1,                          if (x >= clipx2) break;
333                                            (x2 - x1) - 1, h - 2);                          if (x < clipx1) continue;
334                              cr->fill();                          Gdk::Cairo::set_source_rgba(cr, black);
335                              break;                          cr->move_to(x + 0.5, y + 1);
336                            cr->line_to(x + 0.5, y + h - 1);
337                            cr->stroke();
338    
339                            // draw fill for zone
340                            bool isSelectedZone = this->dimzones[dimension].count(j);
341                            Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);
342                            cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
343                            cr->fill();
344    
345                            // draw text showing the beginning of the dimension zone
346                            // as numeric value to the user
347                            {
348                                Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
349                                layout->set_text(Glib::Ascii::dtostr(prevUpperLimit+1));
350                                Gdk::Cairo::set_source_rgba(cr, black);
351                                // get the text dimensions
352                                int text_width, text_height;
353                                layout->get_pixel_size(text_width, text_height);
354                                // move text to the left end of the dimension zone
355                                cr->move_to(prevX + 3, y + (h - text_height) / 2);
356    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
357                                pango_cairo_show_layout(cr->cobj(), layout->gobj());
358    #else
359                                layout->show_in_cairo_context(cr);
360    #endif
361                            }
362                            // draw text showing the end of the dimension zone
363                            // as numeric value to the user
364                            {
365                                Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
366                                layout->set_text(Glib::Ascii::dtostr(upperLimit));
367                                Gdk::Cairo::set_source_rgba(cr, black);
368                                // get the text dimensions
369                                int text_width, text_height;
370                                layout->get_pixel_size(text_width, text_height);
371                                // move text to the left end of the dimension zone
372                                cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
373    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
374                                pango_cairo_show_layout(cr->cobj(), layout->gobj());
375    #else
376                                layout->show_in_cairo_context(cr);
377    #endif
378                          }                          }
379                          x1 = x2;  
380                            prevX = x;
381                            prevUpperLimit = upperLimit;
382                      }                      }
383                  } else {                  } else {
384                      if (dr < nbZones) {                      int prevX = 0;
385                          int x1 = int((w - label_width - 1) * dr / double(nbZones) + 0.5);                      for (int j = 0 ; j <= nbZones ; j++) {
386                          int x2 = int((w - label_width - 1) * (dr + 1) / double(nbZones) + 0.5);                          // draw dimension zone's borders for normal splits
387                          cr->rectangle(label_width + x1 + 1, y + 1,                          int x = int((w - label_width - 1) * j /
388                                        (x2 - x1) - 1, h - 2);                                      double(nbZones) + 0.5) + label_width;
389                          cr->fill();                          if (x >= clipx2) break;
390                      }                          if (x < clipx1) continue;
391                            Gdk::Cairo::set_source_rgba(cr, black);
392                            cr->move_to(x + 0.5, y + 1);
393                            cr->line_to(x + 0.5, y + h - 1);
394                            cr->stroke();
395    
396                            if (j != 0) {
397                                // draw fill for zone
398                                bool isSelectedZone = this->dimzones[dimension].count(j-1);
399                                Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);
400                                cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
401                                cr->fill();
402    
403                                // draw text showing the beginning of the dimension zone
404                                // as numeric value to the user
405                                {
406                                    Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
407                                    layout->set_text(Glib::Ascii::dtostr((j-1) * 128/nbZones));
408                                    Gdk::Cairo::set_source_rgba(cr, black);
409                                    // get the text dimensions
410                                    int text_width, text_height;
411                                    layout->get_pixel_size(text_width, text_height);
412                                    // move text to the left end of the dimension zone
413                                    cr->move_to(prevX + 3, y + (h - text_height) / 2);
414    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
415                                    pango_cairo_show_layout(cr->cobj(), layout->gobj());
416    #else
417                                    layout->show_in_cairo_context(cr);
418    #endif
419                                }
420                                // draw text showing the end of the dimension zone
421                                // as numeric value to the user
422                                {
423                                    Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
424                                    layout->set_text(Glib::Ascii::dtostr(j * 128/nbZones - 1));
425                                    Gdk::Cairo::set_source_rgba(cr, black);
426                                    // get the text dimensions
427                                    int text_width, text_height;
428                                    layout->get_pixel_size(text_width, text_height);
429                                    // move text to the left end of the dimension zone
430                                    cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
431    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
432                                    pango_cairo_show_layout(cr->cobj(), layout->gobj());
433    #else
434                                    layout->show_in_cairo_context(cr);
435    #endif
436                                }
437                            }
438                            prevX = x;
439                        }      
440                  }                  }
441              }              }
   
442              y += h;              y += h;
443          }          }
444          bitpos += region->pDimensionDefinitions[i].bits;          bitpos += region->pDimensionDefinitions[i].bits;
# Line 244  bool DimRegionChooser::on_draw(const Cai Line 450  bool DimRegionChooser::on_draw(const Cai
450  void DimRegionChooser::set_region(gig::Region* region)  void DimRegionChooser::set_region(gig::Region* region)
451  {  {
452      this->region = region;      this->region = region;
453      dimregno = 0;      maindimregno = 0;
454      nbDimensions = 0;      nbDimensions = 0;
455      if (region) {      if (region) {
456          int bitcount = 0;          int bitcount = 0;
# Line 252  void DimRegionChooser::set_region(gig::R Line 458  void DimRegionChooser::set_region(gig::R
458              if (region->pDimensionDefinitions[dim].bits == 0) continue;              if (region->pDimensionDefinitions[dim].bits == 0) continue;
459              nbDimensions++;              nbDimensions++;
460    
461              int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],              int z = std::min(maindimcase[region->pDimensionDefinitions[dim].dimension],
462                               region->pDimensionDefinitions[dim].zones - 1);                               region->pDimensionDefinitions[dim].zones - 1);
463              dimregno |= (z << bitcount);              maindimregno |= (z << bitcount);
464              bitcount += region->pDimensionDefinitions[dim].bits;              bitcount += region->pDimensionDefinitions[dim].bits;
465          }          }
         dimreg = region->pDimensionRegions[dimregno];  
     } else {  
         dimreg = 0;  
466      }      }
467      dimregion_selected();      dimregion_selected();
468      set_size_request(800, region ? nbDimensions * 20 : 0);      set_size_request(800, region ? nbDimensions * h : 0);
469    
470        labels_changed = true;
471      queue_resize();      queue_resize();
472        queue_draw();
473  }  }
474    
475    void DimRegionChooser::refresh_all() {
476        set_region(region);
477    }
478    
479  void DimRegionChooser::get_dimregions(const gig::Region* region, bool stereo,  void DimRegionChooser::get_dimregions(const gig::Region* region, bool stereo,
480                                        std::set<gig::DimensionRegion*>& dimregs) const                                        std::set<gig::DimensionRegion*>& dimregs) const
481  {  {
482      int dimregno = 0;      for (int iDimRgn = 0; iDimRgn < 256; ++iDimRgn) {
483      int bitcount = 0;          gig::DimensionRegion* dimRgn = region->pDimensionRegions[iDimRgn];
484      int stereo_bit = 0;          if (!dimRgn) continue;
485      for (int dim = 0 ; dim < region->Dimensions ; dim++) {          bool isValidZone;
486          if (region->pDimensionDefinitions[dim].bits == 0) continue;          std::map<gig::dimension_t,int> dimCase = caseOfDimRegion(dimRgn, &isValidZone);
487          if (stereo &&          if (!isValidZone) continue;
488              region->pDimensionDefinitions[dim].dimension == gig::dimension_samplechannel) {          for (std::map<gig::dimension_t,int>::const_iterator it = dimCase.begin();
489              stereo_bit = (1 << bitcount);               it != dimCase.end(); ++it)
490          } else {          {
491              int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],              if (stereo && it->first == gig::dimension_samplechannel) continue; // is selected
492                               region->pDimensionDefinitions[dim].zones - 1);  
493              dimregno |= (z << bitcount);              std::map<gig::dimension_t, std::set<int> >::const_iterator itSelectedDimension =
494                    this->dimzones.find(it->first);
495                if (itSelectedDimension != this->dimzones.end() &&
496                    itSelectedDimension->second.count(it->second)) continue; // is selected
497    
498                goto notSelected;
499          }          }
500          bitcount += region->pDimensionDefinitions[dim].bits;  
501            dimregs.insert(dimRgn);
502    
503            notSelected:
504            ;
505      }      }
     dimregs.insert(region->pDimensionRegions[dimregno]);  
     if (stereo_bit) dimregs.insert(region->pDimensionRegions[dimregno | stereo_bit]);  
506  }  }
507    
508    void DimRegionChooser::update_after_resize()
 bool DimRegionChooser::on_button_release_event(GdkEventButton* event)  
509  {  {
510      if (resize.active) {      if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2  
         get_window()->pointer_ungrab(event->time);  
 #else  
         Glib::wrap(event->device, true)->ungrab(event->time);  
 #endif  
         resize.active = false;  
   
         if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {  
511    
512              int bitpos = 0;          int bitpos = 0;
513              for (int j = 0 ; j < resize.dimension ; j++) {          for (int j = 0 ; j < resize.dimension ; j++) {
514                  bitpos += region->pDimensionDefinitions[j].bits;              bitpos += region->pDimensionDefinitions[j].bits;
515            }
516            int mask =
517                ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
518            int c = maindimregno & mask; // mask away this dimension
519    
520            if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {
521                // the velocity dimension didn't previously have
522                // custom v3 splits, so we initialize all splits with
523                // default values
524                int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
525                for (int j = 0 ; j < nbZones ; j++) {
526                    gig::DimensionRegion* d = region->pDimensionRegions[c + (j << bitpos)];
527                    d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
528                }
529            }
530            if (region->pDimensionRegions[c]->VelocityUpperLimit == 0) {
531                // the velocity dimension didn't previously have
532                // custom v2 splits, so we initialize all splits with
533                // default values
534                int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
535                for (int j = 0 ; j < nbZones ; j++) {
536                    gig::DimensionRegion* d = region->pDimensionRegions[c + (j << bitpos)];
537                    d->VelocityUpperLimit = int(128.0 * (j + 1) / nbZones - 1);
538              }              }
539              int mask =          }
540                  ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);  
541              int c = dimregno & mask; // mask away this dimension          gig::DimensionRegion* d = region->pDimensionRegions[c + resize.offset];
542            // update both v2 and v3 values
543              if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {          d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
544                  // the velocity dimension didn't previously have          d->VelocityUpperLimit = resize.pos - 1;
545                  // custom v3 splits, so we initialize all splits with  
546                  // default values      } else {
547                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;          for (int i = 0 ; i < region->DimensionRegions ; ) {
548                  for (int j = 0 ; j < nbZones ; j++) {  
549                      gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];              if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {
550                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);                  // the dimension didn't previously have custom
551                    // limits, so we have to set default limits for
552                    // all the dimension regions
553                    int bitpos = 0;
554                    for (int j = 0 ; j < resize.dimension ; j++) {
555                        bitpos += region->pDimensionDefinitions[j].bits;
556                  }                  }
             }  
             if (region->pDimensionRegions[c]->VelocityUpperLimit == 0) {  
                 // the velocity dimension didn't previously have  
                 // custom v2 splits, so we initialize all splits with  
                 // default values  
557                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
558    
559                  for (int j = 0 ; j < nbZones ; j++) {                  for (int j = 0 ; j < nbZones ; j++) {
560                      gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];                      gig::DimensionRegion* d = region->pDimensionRegions[i + (j << bitpos)];
561                      d->VelocityUpperLimit = int(128.0 * (j + 1) / nbZones - 1);                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
562                  }                  }
563              }              }
564                gig::DimensionRegion* d = region->pDimensionRegions[i + resize.offset];
             gig::DimensionRegion *d = region->pDimensionRegions[c + resize.offset];  
             // update both v2 and v3 values  
565              d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;              d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
             d->VelocityUpperLimit = resize.pos - 1;  
   
         } else {  
             for (int i = 0 ; i < region->DimensionRegions ; ) {  
566    
567                  if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {              int bitpos = 0;
568                      // the dimension didn't previously have custom              int j;
569                      // limits, so we have to set default limits for              for (j = 0 ; j < region->Dimensions ; j++) {
570                      // all the dimension regions                  if (j != resize.dimension) {
571                      int bitpos = 0;                      int maxzones = 1 << region->pDimensionDefinitions[j].bits;
572                      for (int j = 0 ; j < resize.dimension ; j++) {                      int dimj = (i >> bitpos) & (maxzones - 1);
573                          bitpos += region->pDimensionDefinitions[j].bits;                      if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;
                     }  
                     int nbZones = region->pDimensionDefinitions[resize.dimension].zones;  
   
                     for (int j = 0 ; j < nbZones ; j++) {  
                         gig::DimensionRegion *d = region->pDimensionRegions[i + (j << bitpos)];  
                         d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);  
                     }  
                 }  
                 gig::DimensionRegion *d = region->pDimensionRegions[i + resize.offset];  
                 d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;  
   
                 int bitpos = 0;  
                 int j;  
                 for (j = 0 ; j < region->Dimensions ; j++) {  
                     if (j != resize.dimension) {  
                         int maxzones = 1 << region->pDimensionDefinitions[j].bits;  
                         int dimj = (i >> bitpos) & (maxzones - 1);  
                         if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;  
                     }  
                     bitpos += region->pDimensionDefinitions[j].bits;  
574                  }                  }
575                  if (j == region->Dimensions) break;                  bitpos += region->pDimensionDefinitions[j].bits;
                 i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);  
576              }              }
577                if (j == region->Dimensions) break;
578                i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
579          }          }
580        }
581    }
582    
583    bool DimRegionChooser::on_button_release_event(GdkEventButton* event)
584    {
585        if (resize.active) {
586    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
587            get_window()->pointer_ungrab(event->time);
588    #else
589            Glib::wrap(event->device, true)->ungrab(event->time);
590    #endif
591            resize.active = false;
592    
593          region_changed();          region_changed();
594    
595          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {          if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
# Line 424  bool DimRegionChooser::on_button_press_e Line 642  bool DimRegionChooser::on_button_press_e
642              }              }
643    
644              int i = dim;              int i = dim;
645              if (dimregno < 0) dimregno = 0;              if (maindimregno < 0) maindimregno = 0;
646              int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);              int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);
647              int c = dimregno & mask; // mask away this dimension              int c = this->maindimregno & mask; // mask away this dimension
648    
649              bool customsplits =              bool customsplits =
650                  ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&                  ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&
# Line 438  bool DimRegionChooser::on_button_press_e Line 656  bool DimRegionChooser::on_button_press_e
656    
657                  if (region->pDimensionRegions[c]->DimensionUpperLimits[i]) {                  if (region->pDimensionRegions[c]->DimensionUpperLimits[i]) {
658                      for (z = 0 ; z < nbZones ; z++) {                      for (z = 0 ; z < nbZones ; z++) {
659                          gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];                          gig::DimensionRegion* d = region->pDimensionRegions[c + (z << bitpos)];
660                          if (val <= d->DimensionUpperLimits[i]) break;                          if (val <= d->DimensionUpperLimits[i]) break;
661                      }                      }
662                  } else {                  } else {
663                      for (z = 0 ; z < nbZones ; z++) {                      for (z = 0 ; z < nbZones ; z++) {
664                          gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];                          gig::DimensionRegion* d = region->pDimensionRegions[c + (z << bitpos)];
665                          if (val <= d->VelocityUpperLimit) break;                          if (val <= d->VelocityUpperLimit) break;
666                      }                      }
667                  }                  }
# Line 456  bool DimRegionChooser::on_button_press_e Line 674  bool DimRegionChooser::on_button_press_e
674                     region->pDimensionDefinitions[dim].split_type,                     region->pDimensionDefinitions[dim].split_type,
675                     region->pDimensionDefinitions[dim].zones,                     region->pDimensionDefinitions[dim].zones,
676                     region->pDimensionDefinitions[dim].zone_size);                     region->pDimensionDefinitions[dim].zone_size);
677              dimvalue[region->pDimensionDefinitions[dim].dimension] = z;              this->maindimcase[region->pDimensionDefinitions[dim].dimension] = z;
678                this->maindimregno = c | (z << bitpos);
679              dimregno = c | (z << bitpos);              this->maindimtype = region->pDimensionDefinitions[dim].dimension;
680    
681                if (multiSelectKeyDown) {
682                    if (dimzones[this->maindimtype].count(z)) {
683                        if (dimzones[this->maindimtype].size() > 1) {
684                            dimzones[this->maindimtype].erase(z);
685                        }
686                    } else {
687                        dimzones[this->maindimtype].insert(z);
688                    }
689                } else {
690                    this->dimzones.clear();
691                    for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();
692                         it != this->maindimcase.end(); ++it)
693                    {
694                        this->dimzones[it->first].insert(it->second);
695                    }
696                }
697    
698              focus_line = dim;              focus_line = dim;
699              if (has_focus()) queue_draw();              if (has_focus()) queue_draw();
700              else grab_focus();              else grab_focus();
             dimreg = region->pDimensionRegions[dimregno];  
701              dimregion_selected();              dimregion_selected();
702    
703                if (event->button == 3) {
704                    printf("dimregion right click\n");
705                    popup_menu_inside_dimregion->popup(event->button, event->time);
706                }
707    
708                queue_draw();
709          }          }
710      }      }
711      return true;      return true;
# Line 487  bool DimRegionChooser::on_motion_notify_ Line 728  bool DimRegionChooser::on_motion_notify_
728          if (k < 2) k = 2; // k is upper limit + 1, upper limit 0 is forbidden          if (k < 2) k = 2; // k is upper limit + 1, upper limit 0 is forbidden
729    
730          if (k != resize.pos) {          if (k != resize.pos) {
             Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();  
             cr->set_line_width(1);  
   
731              int prevx = int((w - label_width - 1) * resize.pos / 128.0 + 0.5) + label_width;              int prevx = int((w - label_width - 1) * resize.pos / 128.0 + 0.5) + label_width;
732              int x = int((w - label_width - 1) * k / 128.0 + 0.5) + label_width;              int x = int((w - label_width - 1) * k / 128.0 + 0.5) + label_width;
733              int y = resize.dimension * h;              int y = resize.dimension * h;
734                int x1, x2;
735              if (resize.selected == resize.none) {              if (k > resize.pos) {
736                  if (resize.pos != resize.min && resize.pos != resize.max) {                  x1 = prevx;
737                      Gdk::Cairo::set_source_rgba(cr, white);                  x2 = x;
                     cr->move_to(prevx + 0.5, y + 1);  
                     cr->line_to(prevx + 0.5, y + h - 1);  
                     cr->stroke();  
                 }  
738              } else {              } else {
739                  Gdk::RGBA left;                  x1 = x;
740                  Gdk::RGBA right;                  x2 = prevx;
                 if (resize.selected == resize.left) {  
                     left = red;  
                     right = white;  
                 } else {  
                     left = white;  
                     right = red;  
                 }  
   
                 if (k > resize.pos) {  
                     int xx = resize.pos == resize.min ? 1 : 0;  
                     Gdk::Cairo::set_source_rgba(cr, left);  
                     cr->rectangle(prevx + xx, y + 1, x - prevx - xx, h - 2);  
                 } else {  
                     int xx = resize.pos == resize.max ? 0 : 1;  
                     Gdk::Cairo::set_source_rgba(cr, right);  
                     cr->rectangle(x, y + 1, prevx - x + xx, h - 2);  
                 }  
                 cr->fill();  
741              }              }
742              Gdk::Cairo::set_source_rgba(cr, black);              Gdk::Rectangle rect(x1, y + 1, x2 - x1 + 1, h - 2);
             cr->move_to(x + 0.5, y + 1);  
             cr->line_to(x + 0.5, y + h - 1);  
             cr->stroke();  
743    
744              resize.pos = k;              resize.pos = k;
745                update_after_resize();
746                get_window()->invalidate_rect(rect, false); // not sufficient ...
747                queue_draw(); // ... so do a complete redraw instead.
748          }          }
749      } else {      } else {
750          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
# Line 564  bool DimRegionChooser::is_in_resize_zone Line 780  bool DimRegionChooser::is_in_resize_zone
780          int nbZones = region->pDimensionDefinitions[dim].zones;          int nbZones = region->pDimensionDefinitions[dim].zones;
781    
782          int c = 0;          int c = 0;
783          if (dimregno >= 0) {          if (maindimregno >= 0) {
784              int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);              int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);
785              c = dimregno & mask; // mask away this dimension              c = maindimregno & mask; // mask away this dimension
786          }          }
787          const bool customsplits =          const bool customsplits =
788              ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&              ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&
# Line 578  bool DimRegionChooser::is_in_resize_zone Line 794  bool DimRegionChooser::is_in_resize_zone
794          if (region->pDimensionDefinitions[dim].split_type != gig::split_type_bit) {          if (region->pDimensionDefinitions[dim].split_type != gig::split_type_bit) {
795              int prev_limit = 0;              int prev_limit = 0;
796              for (int iZone = 0 ; iZone < nbZones - 1 ; iZone++) {              for (int iZone = 0 ; iZone < nbZones - 1 ; iZone++) {
797                  gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];                  gig::DimensionRegion* d = region->pDimensionRegions[c + (iZone << bitpos)];
798                  const int upperLimit =                  const int upperLimit =
799                      (customsplits) ?                      (customsplits) ?
800                          (d->DimensionUpperLimits[dim]) ?                          (d->DimensionUpperLimits[dim]) ?
# Line 593  bool DimRegionChooser::is_in_resize_zone Line 809  bool DimRegionChooser::is_in_resize_zone
809                      resize.pos = limit;                      resize.pos = limit;
810                      resize.min = prev_limit;                      resize.min = prev_limit;
811    
812                      int dr = (dimregno >> bitpos) &                      int dr = (maindimregno >> bitpos) &
813                          ((1 << region->pDimensionDefinitions[dim].bits) - 1);                          ((1 << region->pDimensionDefinitions[dim].bits) - 1);
814                      resize.selected = dr == iZone ? resize.left :                      resize.selected = dr == iZone ? resize.left :
815                          dr == iZone + 1 ? resize.right : resize.none;                          dr == iZone + 1 ? resize.right : resize.none;
816    
817                      iZone++;                      iZone++;
818                      gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];                      gig::DimensionRegion* d = region->pDimensionRegions[c + (iZone << bitpos)];
819    
820                      const int upperLimit =                      const int upperLimit =
821                          (customsplits) ?                          (customsplits) ?
# Line 630  sigc::signal<void>& DimRegionChooser::si Line 846  sigc::signal<void>& DimRegionChooser::si
846    
847  bool DimRegionChooser::on_focus(Gtk::DirectionType direction)  bool DimRegionChooser::on_focus(Gtk::DirectionType direction)
848  {  {
849      // 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
850      // fokus.      // to set focus
851      if (direction == Gtk::DIR_TAB_FORWARD ||      if (direction == Gtk::DIR_TAB_FORWARD ||
852          direction == Gtk::DIR_DOWN) {          direction == Gtk::DIR_DOWN) {
853          if (!has_focus()) {          if (!has_focus()) {
# Line 663  bool DimRegionChooser::on_focus(Gtk::Dir Line 879  bool DimRegionChooser::on_focus(Gtk::Dir
879              }              }
880          }          }
881      } else if (!has_focus()) {      } else if (!has_focus()) {
882          // TODO: kolla att focus_line finns!          // TODO: check that focus_line exists
883          grab_focus();          grab_focus();
884          return true;          return true;
885      } else {      } else {
886          // TODO: öka eller minska värde!          // TODO: increase or decrease value
887        }
888        return false;
889    }
890    
891    void DimRegionChooser::split_dimension_zone() {    
892        printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
893        try {
894            region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
895        } catch (RIFF::Exception e) {
896            Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
897            msg.run();
898        } catch (...) {
899            Glib::ustring txt = _("An unknown exception occurred!");
900            Gtk::MessageDialog msg(txt, false, Gtk::MESSAGE_ERROR);
901            msg.run();
902        }
903        refresh_all();
904    }
905    
906    void DimRegionChooser::delete_dimension_zone() {
907        printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
908        try {
909            region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
910        } catch (RIFF::Exception e) {
911            Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
912            msg.run();
913        } catch (...) {
914            Glib::ustring txt = _("An unknown exception occurred!");
915            Gtk::MessageDialog msg(txt, false, Gtk::MESSAGE_ERROR);
916            msg.run();
917        }
918        refresh_all();
919    }
920    
921    bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {
922        //printf("key down\n");
923        if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)
924            multiSelectKeyDown = true;
925        return false;
926    }
927    
928    bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {
929        //printf("key up\n");
930        if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)
931            multiSelectKeyDown = false;
932        return false;
933    }
934    
935    void DimRegionChooser::resetSelectedZones() {
936        this->dimzones.clear();
937        if (!region) {
938            queue_draw(); // redraw required parts
939            return;
940        }
941        if (maindimregno < 0 || maindimregno >= region->DimensionRegions) {
942            queue_draw(); // redraw required parts
943            return;
944        }
945        if (!region->pDimensionRegions[maindimregno]) {
946            queue_draw(); // redraw required parts
947            return;
948        }
949        gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];
950    
951        bool isValidZone;
952        this->maindimcase = caseOfDimRegion(dimrgn, &isValidZone);
953        if (!isValidZone) {
954            queue_draw(); // redraw required parts
955            return;
956        }
957    
958        for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();
959             it != this->maindimcase.end(); ++it)
960        {
961            this->dimzones[it->first].insert(it->second);
962        }
963    
964        // redraw required parts
965        queue_draw();
966    }
967    
968    bool DimRegionChooser::select_dimregion(gig::DimensionRegion* dimrgn) {
969        if (!region) return false; //.selection failed
970    
971        for (int dr = 0; dr < region->DimensionRegions && region->pDimensionRegions[dr]; ++dr) {
972            if (region->pDimensionRegions[dr] == dimrgn) {
973                // reset dim region zone selection to the requested specific dim region case
974                maindimregno = dr;
975                resetSelectedZones();
976    
977                // emit signal that dimregion selection has changed, for external entities
978                dimregion_selected();
979    
980                return true; // selection success
981            }
982      }      }
983    
984        return false; //.selection failed
985    }
986    
987    gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {
988        if (!region) return NULL;
989        return region->pDimensionRegions[maindimregno];
990  }  }

Legend:
Removed from v.2169  
changed lines
  Added in v.2841

  ViewVC Help
Powered by ViewVC