/[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 2462 by schoenebeck, Wed Sep 4 20:23:05 2013 UTC revision 2844 by persson, Sun Sep 20 08:49:40 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 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>
26    #include <gtkmm/stock.h>
27    #include <glibmm/ustring.h>
28    #include <gtkmm/messagedialog.h>
29    
30  #include "global.h"  #include "global.h"
31    
32  DimRegionChooser::DimRegionChooser() :  // taken from gdk/gdkkeysyms.h
33    // (define on demand, to avoid unnecessary dev lib package build dependency)
34    #ifndef GDK_KEY_Control_L
35    # define GDK_KEY_Control_L 0xffe3
36    #endif
37    #ifndef GDK_KEY_Control_R
38    # define GDK_KEY_Control_R 0xffe4
39    #endif
40    
41    static std::map<gig::dimension_t,int> caseOfDimRegion(gig::DimensionRegion* dr, bool* isValidZone) {
42        std::map<gig::dimension_t,int> dimCase;
43        if (!dr) {
44            *isValidZone = false;
45            return dimCase;
46        }
47    
48        gig::Region* rgn = (gig::Region*) dr->GetParent();
49    
50        // find the dimension region index of the passed dimension region
51        int drIndex;
52        for (drIndex = 0; drIndex < 256; ++drIndex)
53            if (rgn->pDimensionRegions[drIndex] == dr)
54                break;
55    
56        // not found in region, something's horribly wrong
57        if (drIndex == 256) {
58            fprintf(stderr, "DimRegionChooser: ERROR: index of dim region not found!\n");
59            *isValidZone = false;
60            return std::map<gig::dimension_t,int>();
61        }
62    
63        for (int d = 0, baseBits = 0; d < rgn->Dimensions; ++d) {
64            const int bits = rgn->pDimensionDefinitions[d].bits;
65            dimCase[rgn->pDimensionDefinitions[d].dimension] =
66                (drIndex >> baseBits) & ((1 << bits) - 1);
67            baseBits += bits;
68            // there are also DimensionRegion objects of unused zones, skip them
69            if (dimCase[rgn->pDimensionDefinitions[d].dimension] >= rgn->pDimensionDefinitions[d].zones) {
70                *isValidZone = false;
71                return std::map<gig::dimension_t,int>();
72            }
73        }
74    
75        *isValidZone = true;
76        return dimCase;
77    }
78    
79    DimRegionChooser::DimRegionChooser(Gtk::Window& window) :
80      red("#8070ff"),      red("#8070ff"),
81      black("black"),      black("black"),
82      white("white")      white("white")
83  {  {
84      instrument = 0;      instrument = 0;
85      region = 0;      region = 0;
86      dimregno = -1;      maindimregno = -1;
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;
92      set_can_focus();      set_can_focus();
93    
94        actionGroup = Gtk::ActionGroup::create();
95        actionGroup->add(
96            Gtk::Action::create("SplitDimZone", _("Split Dimensions Zone")),
97            sigc::mem_fun(*this, &DimRegionChooser::split_dimension_zone)
98        );
99        actionGroup->add(
100            Gtk::Action::create("DeleteDimZone", _("Delete Dimension Zone")),
101            sigc::mem_fun(*this, &DimRegionChooser::delete_dimension_zone)
102        );
103    
104        uiManager = Gtk::UIManager::create();
105        uiManager->insert_action_group(actionGroup);
106        Glib::ustring ui_info =
107            "<ui>"
108            "  <popup name='PopupMenuInsideDimRegion'>"
109            "    <menuitem action='SplitDimZone'/>"
110            "    <menuitem action='DeleteDimZone'/>"
111            "  </popup>"
112    //         "  <popup name='PopupMenuOutsideDimRegion'>"
113    //         "    <menuitem action='Add'/>"
114    //         "  </popup>"
115            "</ui>";
116        uiManager->add_ui_from_string(ui_info);
117    
118        popup_menu_inside_dimregion = dynamic_cast<Gtk::Menu*>(
119            uiManager->get_widget("/PopupMenuInsideDimRegion"));
120    //     popup_menu_outside_dimregion = dynamic_cast<Gtk::Menu*>(
121    //         uiManager->get_widget("/PopupMenuOutsideDimRegion"));
122    
123      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |
124                 Gdk::POINTER_MOTION_HINT_MASK);                 Gdk::POINTER_MOTION_HINT_MASK);
125    
     for (int i = 0 ; i < 256 ; i++) dimvalue[i] = 0;  
126      labels_changed = true;      labels_changed = true;
127    
128        set_tooltip_text(_(
129            "Right click here for options on altering dimension zones. Press and "
130            "hold CTRL key for selecting multiple dimension zones simultaniously."
131        ));
132        
133        window.signal_key_press_event().connect(
134            sigc::mem_fun(*this, &DimRegionChooser::onKeyPressed)
135        );
136        window.signal_key_release_event().connect(
137            sigc::mem_fun(*this, &DimRegionChooser::onKeyReleased)
138        );
139  }  }
140    
141  DimRegionChooser::~DimRegionChooser()  DimRegionChooser::~DimRegionChooser()
# Line 58  bool DimRegionChooser::on_expose_event(G Line 152  bool DimRegionChooser::on_expose_event(G
152    
153      const Cairo::RefPtr<Cairo::Context>& cr =      const Cairo::RefPtr<Cairo::Context>& cr =
154          get_window()->create_cairo_context();          get_window()->create_cairo_context();
 #if 0  
 }  
 #endif  
155  #else  #else
156  bool DimRegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)  bool DimRegionChooser::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
157  {  {
# Line 176  bool DimRegionChooser::on_draw(const Cai Line 267  bool DimRegionChooser::on_draw(const Cai
267      for (int i = 0 ; i < region->Dimensions ; i++) {      for (int i = 0 ; i < region->Dimensions ; i++) {
268          int nbZones = region->pDimensionDefinitions[i].zones;          int nbZones = region->pDimensionDefinitions[i].zones;
269          if (nbZones) {          if (nbZones) {
270                const gig::dimension_t dimension = region->pDimensionDefinitions[i].dimension;
271    
272              if (y >= clipy2) break;              if (y >= clipy2) break;
273              if (y + h > clipy1) {              if (y + h > clipy1) {
274                  // draw focus rectangle around dimension's label and zones                  // draw focus rectangle around dimension's label and zones
275                  if (has_focus() && focus_line == i) {                  if (has_focus() && focus_line == i) {
276  #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
277                      Gdk::Rectangle farea(0, y, 150, 20);                      Gdk::Rectangle farea(0, y, 150, h);
278                      get_style()->paint_focus(get_window(), get_state(), farea,                      get_style()->paint_focus(get_window(), get_state(), farea,
279                                               *this, "",                                               *this, "",
280                                               0, y, label_width, 20);                                               0, y, label_width, h);
281  #else  #else
282                      get_style_context()->render_focus(cr,                      get_style_context()->render_focus(cr,
283                                                        0, y, label_width, 20);                                                        0, y, label_width, h);
284  #endif  #endif
285                  }                  }
286    
# Line 206  bool DimRegionChooser::on_draw(const Cai Line 299  bool DimRegionChooser::on_draw(const Cai
299                  cr->fill();                  cr->fill();
300    
301                  int c = 0;                  int c = 0;
302                  if (dimregno >= 0) {                  if (maindimregno >= 0) {
303                      int mask =                      int mask =
304                          ~(((1 << region->pDimensionDefinitions[i].bits) - 1) <<                          ~(((1 << region->pDimensionDefinitions[i].bits) - 1) <<
305                            bitpos);                            bitpos);
306                      c = dimregno & mask; // mask away this dimension                      c = maindimregno & mask; // mask away this dimension
307                  }                  }
308                  bool customsplits =                  bool customsplits =
309                      ((region->pDimensionDefinitions[i].split_type ==                      ((region->pDimensionDefinitions[i].split_type ==
# Line 220  bool DimRegionChooser::on_draw(const Cai Line 313  bool DimRegionChooser::on_draw(const Cai
313                        gig::dimension_velocity &&                        gig::dimension_velocity &&
314                        region->pDimensionRegions[c]->VelocityUpperLimit));                        region->pDimensionRegions[c]->VelocityUpperLimit));
315    
316                  // draw dimension's zone borders                  // draw dimension zones
317                  Gdk::Cairo::set_source_rgba(cr, black);                  Gdk::Cairo::set_source_rgba(cr, black);
318                  if (customsplits) {                  if (customsplits) {
319                      cr->move_to(label_width + 0.5, y + 1);                      cr->move_to(label_width + 0.5, y + 1);
320                      cr->line_to(label_width + 0.5, y + h - 1);                      cr->line_to(label_width + 0.5, y + h - 1);
321                        int prevX = label_width;
322                        int prevUpperLimit = -1;
323    
324                      for (int j = 0 ; j < nbZones ; j++) {                      for (int j = 0 ; j < nbZones ; j++) {
325                            // draw dimension zone's borders for custom splits
326                          gig::DimensionRegion* d =                          gig::DimensionRegion* d =
327                              region->pDimensionRegions[c + (j << bitpos)];                              region->pDimensionRegions[c + (j << bitpos)];
328                          int upperLimit = d->DimensionUpperLimits[i];                          int upperLimit = d->DimensionUpperLimits[i];
# Line 236  bool DimRegionChooser::on_draw(const Cai Line 332  bool DimRegionChooser::on_draw(const Cai
332                              label_width;                              label_width;
333                          if (x >= clipx2) break;                          if (x >= clipx2) break;
334                          if (x < clipx1) continue;                          if (x < clipx1) continue;
335                            Gdk::Cairo::set_source_rgba(cr, black);
336                          cr->move_to(x + 0.5, y + 1);                          cr->move_to(x + 0.5, y + 1);
337                          cr->line_to(x + 0.5, y + h - 1);                          cr->line_to(x + 0.5, y + h - 1);
338                            cr->stroke();
339    
340                            // draw fill for zone
341                            bool isSelectedZone = this->dimzones[dimension].count(j);
342                            Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);
343                            cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
344                            cr->fill();
345    
346                            // draw text showing the beginning of the dimension zone
347                            // as numeric value to the user
348                            {
349                                Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
350                                layout->set_text(Glib::Ascii::dtostr(prevUpperLimit+1));
351                                Gdk::Cairo::set_source_rgba(cr, black);
352                                // get the text dimensions
353                                int text_width, text_height;
354                                layout->get_pixel_size(text_width, text_height);
355                                // move text to the left end of the dimension zone
356                                cr->move_to(prevX + 3, y + (h - text_height) / 2);
357    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
358                                pango_cairo_show_layout(cr->cobj(), layout->gobj());
359    #else
360                                layout->show_in_cairo_context(cr);
361    #endif
362                            }
363                            // draw text showing the end of the dimension zone
364                            // as numeric value to the user
365                            {
366                                Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
367                                layout->set_text(Glib::Ascii::dtostr(upperLimit));
368                                Gdk::Cairo::set_source_rgba(cr, black);
369                                // get the text dimensions
370                                int text_width, text_height;
371                                layout->get_pixel_size(text_width, text_height);
372                                // move text to the left end of the dimension zone
373                                cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
374    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
375                                pango_cairo_show_layout(cr->cobj(), layout->gobj());
376    #else
377                                layout->show_in_cairo_context(cr);
378    #endif
379                            }
380    
381                            prevX = x;
382                            prevUpperLimit = upperLimit;
383                      }                      }
384                  } else {                  } else {
385                        int prevX = 0;
386                      for (int j = 0 ; j <= nbZones ; j++) {                      for (int j = 0 ; j <= nbZones ; j++) {
387                            // draw dimension zone's borders for normal splits
388                          int x = int((w - label_width - 1) * j /                          int x = int((w - label_width - 1) * j /
389                                      double(nbZones) + 0.5) + label_width;                                      double(nbZones) + 0.5) + label_width;
390                          if (x >= clipx2) break;                          if (x >= clipx2) break;
391                          if (x < clipx1) continue;                          if (x < clipx1) continue;
392                            Gdk::Cairo::set_source_rgba(cr, black);
393                          cr->move_to(x + 0.5, y + 1);                          cr->move_to(x + 0.5, y + 1);
394                          cr->line_to(x + 0.5, y + h - 1);                          cr->line_to(x + 0.5, y + h - 1);
395                      }                          cr->stroke();
                 }  
                 cr->stroke();  
396    
397                  // draw fill for currently selected zone                          if (j != 0) {
398                  if (dimregno >= 0) {                              // draw fill for zone
399                      Gdk::Cairo::set_source_rgba(cr, red);                              bool isSelectedZone = this->dimzones[dimension].count(j-1);
400                      int dr = (dimregno >> bitpos) &                              Gdk::Cairo::set_source_rgba(cr, isSelectedZone ? red : white);
401                          ((1 << region->pDimensionDefinitions[i].bits) - 1);                              cr->rectangle(prevX + 1, y + 1, x - prevX - 1, h - 1);
                       
                     int x1 = -1, x2 = -1;  
                     if (customsplits) {  
                         x1 = label_width;  
                         for (int j = 0 ; j < nbZones && x1 + 1 < clipx2 ; j++) {  
                             gig::DimensionRegion* d =  
                                 region->pDimensionRegions[c + (j << bitpos)];  
                             int upperLimit = d->DimensionUpperLimits[i];  
                             if (!upperLimit) {  
                                 upperLimit = d->VelocityUpperLimit;  
                             }  
                             int v = upperLimit + 1;  
                             x2 = int((w - label_width - 1) * v / 128.0 +  
                                      0.5) + label_width;  
                             if (j == dr && x1 < x2) {  
                                 cr->rectangle(x1 + 1, y + 1,  
                                               (x2 - x1) - 1, h - 2);  
                                 cr->fill();  
                                 break;  
                             }  
                             x1 = x2;  
                         }  
                     } else {  
                         if (dr < nbZones) {  
                             x1 = int((w - label_width - 1) * dr /  
                                      double(nbZones) + 0.5);  
                             x2 = int((w - label_width - 1) * (dr + 1) /  
                                      double(nbZones) + 0.5);  
                             cr->rectangle(label_width + x1 + 1, y + 1,  
                                           (x2 - x1) - 1, h - 2);  
402                              cr->fill();                              cr->fill();
                         }  
                     }  
403    
404                      // draw text showing the beginning of the dimension zone                              // draw text showing the beginning of the dimension zone
405                      // as numeric value to the user                              // as numeric value to the user
406                      if (x1 >= 0) {                              {
407                          Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
408                          int v = roundf(float(x1 - label_width) / float(w - label_width) * 127.f);                                  layout->set_text(Glib::Ascii::dtostr((j-1) * 128/nbZones));
409                          if (dr > 0) v++;                                  Gdk::Cairo::set_source_rgba(cr, black);
410                          layout->set_text(Glib::Ascii::dtostr(v));                                  // get the text dimensions
411                          Gdk::Cairo::set_source_rgba(cr, black);                                  int text_width, text_height;
412                          Pango::Rectangle rect = layout->get_logical_extents();                                  layout->get_pixel_size(text_width, text_height);
413                                                            // move text to the left end of the dimension zone
414                          int text_width, text_height;                                  cr->move_to(prevX + 3, y + (h - text_height) / 2);
                         // get the text dimensions  
                         layout->get_pixel_size(text_width, text_height);  
                         // move text to the right end of the dimension zone  
                         cr->move_to(x1 + 1, y + 1);  
415  #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
416                          pango_cairo_show_layout(cr->cobj(), layout->gobj());                                  pango_cairo_show_layout(cr->cobj(), layout->gobj());
417  #else  #else
418                          layout->show_in_cairo_context(cr);                                  layout->show_in_cairo_context(cr);
419  #endif  #endif
420                      }                              }
421                      // draw text showing the end of the dimension zone                              // draw text showing the end of the dimension zone
422                      // as numeric value to the user                              // as numeric value to the user
423                      if (x2 >= 0) {                              {
424                          Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);                                  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
425                          const int v = roundf(float(x2 - label_width) / float(w - label_width) * 127.f);                                  layout->set_text(Glib::Ascii::dtostr(j * 128/nbZones - 1));
426                          layout->set_text(Glib::Ascii::dtostr(v));                                  Gdk::Cairo::set_source_rgba(cr, black);
427                          Gdk::Cairo::set_source_rgba(cr, black);                                  // get the text dimensions
428                          Pango::Rectangle rect = layout->get_logical_extents();                                  int text_width, text_height;
429                                                            layout->get_pixel_size(text_width, text_height);
430                          int text_width, text_height;                                  // move text to the left end of the dimension zone
431                          // get the text dimensions                                  cr->move_to(x - 3 - text_width, y + (h - text_height) / 2);
                         layout->get_pixel_size(text_width, text_height);  
                         // move text to the right end of the dimension zone  
                         cr->move_to(x2 - text_width - 1, y + 1);  
432  #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
433                          pango_cairo_show_layout(cr->cobj(), layout->gobj());                                  pango_cairo_show_layout(cr->cobj(), layout->gobj());
434  #else  #else
435                          layout->show_in_cairo_context(cr);                                  layout->show_in_cairo_context(cr);
436  #endif  #endif
437                      }                              }
438                            }
439                            prevX = x;
440                        }      
441                  }                  }
442              }              }
   
443              y += h;              y += h;
444          }          }
445          bitpos += region->pDimensionDefinitions[i].bits;          bitpos += region->pDimensionDefinitions[i].bits;
# Line 345  bool DimRegionChooser::on_draw(const Cai Line 451  bool DimRegionChooser::on_draw(const Cai
451  void DimRegionChooser::set_region(gig::Region* region)  void DimRegionChooser::set_region(gig::Region* region)
452  {  {
453      this->region = region;      this->region = region;
454      dimregno = 0;      maindimregno = 0;
455      nbDimensions = 0;      nbDimensions = 0;
456      if (region) {      if (region) {
457          int bitcount = 0;          int bitcount = 0;
# Line 353  void DimRegionChooser::set_region(gig::R Line 459  void DimRegionChooser::set_region(gig::R
459              if (region->pDimensionDefinitions[dim].bits == 0) continue;              if (region->pDimensionDefinitions[dim].bits == 0) continue;
460              nbDimensions++;              nbDimensions++;
461    
462              int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],              int z = std::min(maindimcase[region->pDimensionDefinitions[dim].dimension],
463                               region->pDimensionDefinitions[dim].zones - 1);                               region->pDimensionDefinitions[dim].zones - 1);
464              dimregno |= (z << bitcount);              maindimregno |= (z << bitcount);
465              bitcount += region->pDimensionDefinitions[dim].bits;              bitcount += region->pDimensionDefinitions[dim].bits;
466          }          }
         dimreg = region->pDimensionRegions[dimregno];  
     } else {  
         dimreg = 0;  
467      }      }
468      dimregion_selected();      dimregion_selected();
469      set_size_request(800, region ? nbDimensions * 20 : 0);      set_size_request(800, region ? nbDimensions * h : 0);
470    
471      labels_changed = true;      labels_changed = true;
472      queue_resize();      queue_resize();
473        queue_draw();
474  }  }
475    
476    void DimRegionChooser::refresh_all() {
477        set_region(region);
478    }
479    
480  void DimRegionChooser::get_dimregions(const gig::Region* region, bool stereo,  void DimRegionChooser::get_dimregions(const gig::Region* region, bool stereo,
481                                        std::set<gig::DimensionRegion*>& dimregs) const                                        std::set<gig::DimensionRegion*>& dimregs) const
482  {  {
483      int dimregno = 0;      for (int iDimRgn = 0; iDimRgn < 256; ++iDimRgn) {
484      int bitcount = 0;          gig::DimensionRegion* dimRgn = region->pDimensionRegions[iDimRgn];
485      int stereo_bit = 0;          if (!dimRgn) continue;
486      for (int dim = 0 ; dim < region->Dimensions ; dim++) {          bool isValidZone;
487          if (region->pDimensionDefinitions[dim].bits == 0) continue;          std::map<gig::dimension_t,int> dimCase = caseOfDimRegion(dimRgn, &isValidZone);
488          if (stereo &&          if (!isValidZone) continue;
489              region->pDimensionDefinitions[dim].dimension == gig::dimension_samplechannel) {          for (std::map<gig::dimension_t,int>::const_iterator it = dimCase.begin();
490              stereo_bit = (1 << bitcount);               it != dimCase.end(); ++it)
491          } else {          {
492              int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],              if (stereo && it->first == gig::dimension_samplechannel) continue; // is selected
493                               region->pDimensionDefinitions[dim].zones - 1);  
494              dimregno |= (z << bitcount);              std::map<gig::dimension_t, std::set<int> >::const_iterator itSelectedDimension =
495                    this->dimzones.find(it->first);
496                if (itSelectedDimension != this->dimzones.end() &&
497                    itSelectedDimension->second.count(it->second)) continue; // is selected
498    
499                goto notSelected;
500          }          }
501          bitcount += region->pDimensionDefinitions[dim].bits;  
502            dimregs.insert(dimRgn);
503    
504            notSelected:
505            ;
506      }      }
     dimregs.insert(region->pDimensionRegions[dimregno]);  
     if (stereo_bit) dimregs.insert(region->pDimensionRegions[dimregno | stereo_bit]);  
507  }  }
508    
509  void DimRegionChooser::update_after_resize()  void DimRegionChooser::update_after_resize()
# Line 402  void DimRegionChooser::update_after_resi Line 516  void DimRegionChooser::update_after_resi
516          }          }
517          int mask =          int mask =
518              ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);              ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
519          int c = dimregno & mask; // mask away this dimension          int c = maindimregno & mask; // mask away this dimension
520    
521          if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {          if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {
522              // the velocity dimension didn't previously have              // the velocity dimension didn't previously have
# Line 529  bool DimRegionChooser::on_button_press_e Line 643  bool DimRegionChooser::on_button_press_e
643              }              }
644    
645              int i = dim;              int i = dim;
646              if (dimregno < 0) dimregno = 0;              if (maindimregno < 0) maindimregno = 0;
647              int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);              int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);
648              int c = dimregno & mask; // mask away this dimension              int c = this->maindimregno & mask; // mask away this dimension
649    
650              bool customsplits =              bool customsplits =
651                  ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&                  ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&
# Line 561  bool DimRegionChooser::on_button_press_e Line 675  bool DimRegionChooser::on_button_press_e
675                     region->pDimensionDefinitions[dim].split_type,                     region->pDimensionDefinitions[dim].split_type,
676                     region->pDimensionDefinitions[dim].zones,                     region->pDimensionDefinitions[dim].zones,
677                     region->pDimensionDefinitions[dim].zone_size);                     region->pDimensionDefinitions[dim].zone_size);
678              dimvalue[region->pDimensionDefinitions[dim].dimension] = z;              this->maindimcase[region->pDimensionDefinitions[dim].dimension] = z;
679                this->maindimregno = c | (z << bitpos);
680              dimregno = c | (z << bitpos);              this->maindimtype = region->pDimensionDefinitions[dim].dimension;
681    
682                if (multiSelectKeyDown) {
683                    if (dimzones[this->maindimtype].count(z)) {
684                        if (dimzones[this->maindimtype].size() > 1) {
685                            dimzones[this->maindimtype].erase(z);
686                        }
687                    } else {
688                        dimzones[this->maindimtype].insert(z);
689                    }
690                } else {
691                    this->dimzones.clear();
692                    for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();
693                         it != this->maindimcase.end(); ++it)
694                    {
695                        this->dimzones[it->first].insert(it->second);
696                    }
697                }
698    
699              focus_line = dim;              focus_line = dim;
700              if (has_focus()) queue_draw();              if (has_focus()) queue_draw();
701              else grab_focus();              else grab_focus();
             dimreg = region->pDimensionRegions[dimregno];  
702              dimregion_selected();              dimregion_selected();
703    
704                if (event->button == 3) {
705                    printf("dimregion right click\n");
706                    popup_menu_inside_dimregion->popup(event->button, event->time);
707                }
708    
709                queue_draw();
710          }          }
711      }      }
712      return true;      return true;
# Line 607  bool DimRegionChooser::on_motion_notify_ Line 744  bool DimRegionChooser::on_motion_notify_
744    
745              resize.pos = k;              resize.pos = k;
746              update_after_resize();              update_after_resize();
747              get_window()->invalidate_rect(rect, false);              get_window()->invalidate_rect(rect, false); // not sufficient ...
748                queue_draw(); // ... so do a complete redraw instead.
749          }          }
750      } else {      } else {
751          if (is_in_resize_zone(x, y)) {          if (is_in_resize_zone(x, y)) {
# Line 643  bool DimRegionChooser::is_in_resize_zone Line 781  bool DimRegionChooser::is_in_resize_zone
781          int nbZones = region->pDimensionDefinitions[dim].zones;          int nbZones = region->pDimensionDefinitions[dim].zones;
782    
783          int c = 0;          int c = 0;
784          if (dimregno >= 0) {          if (maindimregno >= 0) {
785              int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);              int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);
786              c = dimregno & mask; // mask away this dimension              c = maindimregno & mask; // mask away this dimension
787          }          }
788          const bool customsplits =          const bool customsplits =
789              ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&              ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&
# Line 672  bool DimRegionChooser::is_in_resize_zone Line 810  bool DimRegionChooser::is_in_resize_zone
810                      resize.pos = limit;                      resize.pos = limit;
811                      resize.min = prev_limit;                      resize.min = prev_limit;
812    
813                      int dr = (dimregno >> bitpos) &                      int dr = (maindimregno >> bitpos) &
814                          ((1 << region->pDimensionDefinitions[dim].bits) - 1);                          ((1 << region->pDimensionDefinitions[dim].bits) - 1);
815                      resize.selected = dr == iZone ? resize.left :                      resize.selected = dr == iZone ? resize.left :
816                          dr == iZone + 1 ? resize.right : resize.none;                          dr == iZone + 1 ? resize.right : resize.none;
# Line 709  sigc::signal<void>& DimRegionChooser::si Line 847  sigc::signal<void>& DimRegionChooser::si
847    
848  bool DimRegionChooser::on_focus(Gtk::DirectionType direction)  bool DimRegionChooser::on_focus(Gtk::DirectionType direction)
849  {  {
850      // 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
851      // fokus.      // to set focus
852      if (direction == Gtk::DIR_TAB_FORWARD ||      if (direction == Gtk::DIR_TAB_FORWARD ||
853          direction == Gtk::DIR_DOWN) {          direction == Gtk::DIR_DOWN) {
854          if (!has_focus()) {          if (!has_focus()) {
# Line 742  bool DimRegionChooser::on_focus(Gtk::Dir Line 880  bool DimRegionChooser::on_focus(Gtk::Dir
880              }              }
881          }          }
882      } else if (!has_focus()) {      } else if (!has_focus()) {
883          // TODO: kolla att focus_line finns!          // TODO: check that focus_line exists
884          grab_focus();          grab_focus();
885          return true;          return true;
886      } else {      } else {
887          // TODO: öka eller minska värde!          // TODO: increase or decrease value
888        }
889        return false;
890    }
891    
892    void DimRegionChooser::split_dimension_zone() {    
893        printf("split_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
894        try {
895            region->SplitDimensionZone(maindimtype, maindimcase[maindimtype]);
896        } catch (RIFF::Exception e) {
897            Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
898            msg.run();
899        } catch (...) {
900            Glib::ustring txt = _("An unknown exception occurred!");
901            Gtk::MessageDialog msg(txt, false, Gtk::MESSAGE_ERROR);
902            msg.run();
903      }      }
904        refresh_all();
905    }
906    
907    void DimRegionChooser::delete_dimension_zone() {
908        printf("delete_dimension_zone() type=%d, zone=%d\n", maindimtype, maindimcase[maindimtype]);
909        try {
910            region->DeleteDimensionZone(maindimtype, maindimcase[maindimtype]);
911        } catch (RIFF::Exception e) {
912            Gtk::MessageDialog msg(e.Message, false, Gtk::MESSAGE_ERROR);
913            msg.run();
914        } catch (...) {
915            Glib::ustring txt = _("An unknown exception occurred!");
916            Gtk::MessageDialog msg(txt, false, Gtk::MESSAGE_ERROR);
917            msg.run();
918        }
919        refresh_all();
920    }
921    
922    bool DimRegionChooser::onKeyPressed(GdkEventKey* key) {
923        //printf("key down\n");
924        if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)
925            multiSelectKeyDown = true;
926        return false;
927    }
928    
929    bool DimRegionChooser::onKeyReleased(GdkEventKey* key) {
930        //printf("key up\n");
931        if (key->keyval == GDK_KEY_Control_L || key->keyval == GDK_KEY_Control_R)
932            multiSelectKeyDown = false;
933        return false;
934    }
935    
936    void DimRegionChooser::resetSelectedZones() {
937        this->dimzones.clear();
938        if (!region) {
939            queue_draw(); // redraw required parts
940            return;
941        }
942        if (maindimregno < 0 || maindimregno >= region->DimensionRegions) {
943            queue_draw(); // redraw required parts
944            return;
945        }
946        if (!region->pDimensionRegions[maindimregno]) {
947            queue_draw(); // redraw required parts
948            return;
949        }
950        gig::DimensionRegion* dimrgn = region->pDimensionRegions[maindimregno];
951    
952        bool isValidZone;
953        this->maindimcase = caseOfDimRegion(dimrgn, &isValidZone);
954        if (!isValidZone) {
955            queue_draw(); // redraw required parts
956            return;
957        }
958    
959        for (std::map<gig::dimension_t,int>::const_iterator it = this->maindimcase.begin();
960             it != this->maindimcase.end(); ++it)
961        {
962            this->dimzones[it->first].insert(it->second);
963        }
964    
965        // redraw required parts
966        queue_draw();
967    }
968    
969    bool DimRegionChooser::select_dimregion(gig::DimensionRegion* dimrgn) {
970        if (!region) return false; //.selection failed
971    
972        for (int dr = 0; dr < region->DimensionRegions && region->pDimensionRegions[dr]; ++dr) {
973            if (region->pDimensionRegions[dr] == dimrgn) {
974                // reset dim region zone selection to the requested specific dim region case
975                maindimregno = dr;
976                resetSelectedZones();
977    
978                // emit signal that dimregion selection has changed, for external entities
979                dimregion_selected();
980    
981                return true; // selection success
982            }
983        }
984    
985        return false; //.selection failed
986    }
987    
988    gig::DimensionRegion* DimRegionChooser::get_main_dimregion() const {
989        if (!region) return NULL;
990        return region->pDimensionRegions[maindimregno];
991  }  }

Legend:
Removed from v.2462  
changed lines
  Added in v.2844

  ViewVC Help
Powered by ViewVC