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

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

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

revision 1089 by persson, Sat Mar 10 08:58:30 2007 UTC revision 1092 by persson, Sun Mar 11 15:21:58 2007 UTC
# Line 18  Line 18 
18   */   */
19    
20  #include "dimregionchooser.h"  #include "dimregionchooser.h"
21    #include <gdkmm/cursor.h>
22    
23  DimRegionChooser::DimRegionChooser()  DimRegionChooser::DimRegionChooser()
24  {  {
# Line 40  DimRegionChooser::DimRegionChooser() Line 41  DimRegionChooser::DimRegionChooser()
41      region = 0;      region = 0;
42      dimregno = -1;      dimregno = -1;
43      focus_line = 0;      focus_line = 0;
44        resize.active = false;
45        cursor_is_resize = false;
46        h = 20;
47        w = 800;
48      set_flags(Gtk::CAN_FOCUS);      set_flags(Gtk::CAN_FOCUS);
49      add_events(Gdk::BUTTON_PRESS_MASK);      add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |
50                   Gdk::POINTER_MOTION_HINT_MASK);
51    
52      for (int i = 0 ; i < 256 ; i++) {      for (int i = 0 ; i < 256 ; i++) {
53          dimvalue_from[i] = 0;          dimvalue_from[i] = 0;
# Line 74  bool DimRegionChooser::on_expose_event(G Line 80  bool DimRegionChooser::on_expose_event(G
80      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);      Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
81    
82      window->clear();      window->clear();
     const int h = 20;  
     const int w = 800;  
83      int y = 0;      int y = 0;
84      double maxwidth = 0;      double maxwidth = 0;
85      for (int i = 0 ; i < region->Dimensions ; i++) {      for (int i = 0 ; i < region->Dimensions ; i++) {
# Line 146  bool DimRegionChooser::on_expose_event(G Line 150  bool DimRegionChooser::on_expose_event(G
150    
151              if (has_focus() && focus_line == i) {              if (has_focus() && focus_line == i) {
152                  Gdk::Rectangle farea(0, y, 150, 20);                  Gdk::Rectangle farea(0, y, 150, 20);
153                  get_style()->paint_focus(window, get_state(), farea, *this, "", 0, y, label_width, 20);                  get_style()->paint_focus(window, get_state(), farea, *this, "",
154                                             0, y, label_width, 20);
155              }              }
156    
157              Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();              Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
158              window->draw_line(black, label_width, y, w - 1, y);              window->draw_line(black, label_width, y, w - 1, y);
159              window->draw_line(black, w - 1, y + h - 1, label_width, y + h - 1);              window->draw_line(black, w - 1, y + h - 1, label_width, y + h - 1);
160              window->draw_rectangle(get_style()->get_white_gc(), true, label_width + 1, y + 1, (w - label_width - 2), h - 2);              window->draw_rectangle(get_style()->get_white_gc(), true,
161                                       label_width + 1, y + 1, (w - label_width - 2), h - 2);
162    
163              int c = 0;              int c = 0;
164              if (dimregno >= 0) {              if (dimregno >= 0) {
# Line 194  bool DimRegionChooser::on_expose_event(G Line 200  bool DimRegionChooser::on_expose_event(G
200                          int v = upperLimit + 1;                          int v = upperLimit + 1;
201                          int x2 = int((w - label_width - 1) * v / 128.0 + 0.5);                          int x2 = int((w - label_width - 1) * v / 128.0 + 0.5);
202                          if (j == dr && x1 < x2) {                          if (j == dr && x1 < x2) {
203                              window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1, (x2 - x1) - 1, h - 2);                              window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1,
204                                                       (x2 - x1) - 1, h - 2);
205                              break;                              break;
206                          }                          }
207                          x1 = x2;                          x1 = x2;
# Line 203  bool DimRegionChooser::on_expose_event(G Line 210  bool DimRegionChooser::on_expose_event(G
210                      if (dr < nbZones) {                      if (dr < nbZones) {
211                          int x1 = int((w - label_width - 1) * dr / double(nbZones) + 0.5);                          int x1 = int((w - label_width - 1) * dr / double(nbZones) + 0.5);
212                          int x2 = int((w - label_width - 1) * (dr + 1) / double(nbZones) + 0.5);                          int x2 = int((w - label_width - 1) * (dr + 1) / double(nbZones) + 0.5);
213                          window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1, (x2 - x1) - 1, h - 2);                          window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1,
214                                                   (x2 - x1) - 1, h - 2);
215                      }                      }
216                  }                  }
217              }              }
# Line 216  bool DimRegionChooser::on_expose_event(G Line 224  bool DimRegionChooser::on_expose_event(G
224      return true;      return true;
225  }  }
226    
   
227  void DimRegionChooser::on_size_request(GtkRequisition* requisition)  void DimRegionChooser::on_size_request(GtkRequisition* requisition)
228  {  {
229      printf("DimRegionChooser::on_size_request\n");      printf("DimRegionChooser::on_size_request\n");
# Line 273  void DimRegionChooser::set_region(gig::R Line 280  void DimRegionChooser::set_region(gig::R
280    }    }
281  */  */
282    
283  bool DimRegionChooser::on_button_press_event(GdkEventButton* event)  bool DimRegionChooser::on_button_release_event(GdkEventButton* event)
284  {  {
285      const int h = 20;      if (resize.active) {
286      const int w = 800;          get_window()->pointer_ungrab(event->time);
287            resize.active = false;
288    
289            if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
290    
291                int bitpos = 0;
292                for (int j = 0 ; j < resize.dimension ; j++) {
293                    bitpos += region->pDimensionDefinitions[j].bits;
294                }
295                int mask =
296                         ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
297                int c = dimregno & mask; // mask away this dimension
298    
299                gig::DimensionRegion *d = region->pDimensionRegions[c + resize.offset];
300                if (d->DimensionUpperLimits[resize.dimension]) {
301                    d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
302                } else {
303                    d->VelocityUpperLimit = resize.pos - 1;
304                }
305    
306            } else {
307                for (int i = 0 ; i < region->DimensionRegions ; ) {
308    
309                    gig::DimensionRegion *d = region->pDimensionRegions[i + resize.offset];
310                    d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
311    
312      if (region) {                  int bitpos = 0;
313          if (event->y < nbDimensions * h &&                  int j;
314              event->x >= label_width && event->x < w) {                  for (j = 0 ; j < region->Dimensions ; j++) {
315                        if (j != resize.dimension) {
316                            int maxzones = 1 << region->pDimensionDefinitions[j].bits;
317                            int dimj = (i >> bitpos) & (maxzones - 1);
318                            if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;
319                        }
320                        bitpos += region->pDimensionDefinitions[j].bits;
321                    }
322                    if (j == region->Dimensions) break;
323                    i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
324                }
325            }
326    
327            if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
328                get_window()->set_cursor();
329                cursor_is_resize = false;
330            }
331        }
332        return true;
333    }
334    
335    bool DimRegionChooser::on_button_press_event(GdkEventButton* event)
336    {
337        if (region && event->y < nbDimensions * h &&
338            event->x >= label_width && event->x < w) {
339    
340            if (is_in_resize_zone(event->x, event->y)) {
341                Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
342                get_window()->pointer_grab(false,
343                                           Gdk::BUTTON_RELEASE_MASK |
344                                           Gdk::POINTER_MOTION_MASK |
345                                           Gdk::POINTER_MOTION_HINT_MASK,
346                                           double_arrow, event->time);
347                resize.active = true;
348            } else {
349              int ydim = int(event->y / h);              int ydim = int(event->y / h);
350              int dim;              int dim;
351              for (dim = 0 ; dim < region->Dimensions ; dim++) {              for (dim = 0 ; dim < region->Dimensions ; dim++) {
# Line 357  bool DimRegionChooser::on_button_press_e Line 421  bool DimRegionChooser::on_button_press_e
421      return true;      return true;
422  }  }
423    
424    bool DimRegionChooser::on_motion_notify_event(GdkEventMotion* event)
425    {
426        Glib::RefPtr<Gdk::Window> window = get_window();
427        int x, y;
428        Gdk::ModifierType state = Gdk::ModifierType(0);
429        window->get_pointer(x, y, state);
430    
431        if (resize.active) {
432            int k = int((x - label_width) * 128.0 / (w - label_width - 1) + 0.5);
433    
434            if (k < resize.min) k = resize.min;
435            else if (k > resize.max) k = resize.max;
436    
437            if (k < 2) k = 2; // k is upper limit + 1, upper limit 0 is forbidden
438    
439            if (k != resize.pos) {
440                Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
441                Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();
442    
443                int prevx = int((w - label_width - 1) * resize.pos / 128.0 + 0.5) + label_width;
444                int x = int((w - label_width - 1) * k / 128.0 + 0.5) + label_width;
445                int y = resize.dimension * h;
446    
447                if (resize.selected == resize.none) {
448                    if (resize.pos != resize.min && resize.pos != resize.max) {
449                        window->draw_line(white, prevx, y + 1, prevx, y + h - 2);
450                    }
451                } else {
452                    gc->set_foreground(red);
453    
454                    Glib::RefPtr<const Gdk::GC> left;
455                    Glib::RefPtr<const Gdk::GC> right;
456                    if (resize.selected == resize.left) {
457                        left = gc;
458                        right = white;
459                    } else {
460                        left = white;
461                        right = gc;
462                    }
463    
464                    if (k > resize.pos) {
465                        int xx = resize.pos == resize.min ? 1 : 0;
466                        window->draw_rectangle(left, true,
467                                               prevx + xx, y + 1, x - prevx - xx, h - 2);
468                    } else {
469                        int xx = resize.pos == resize.max ? 0 : 1;
470                        window->draw_rectangle(right, true,
471                                               x, y + 1, prevx - x + xx, h - 2);
472                    }
473                }
474                window->draw_line(black, x, y + 1, x, y + h - 2);
475                resize.pos = k;
476            }
477        } else {
478            if (is_in_resize_zone(x, y)) {
479                if (!cursor_is_resize) {
480                    Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
481                    window->set_cursor(double_arrow);
482                    cursor_is_resize = true;
483                }
484            } else if (cursor_is_resize) {
485                window->set_cursor();
486                cursor_is_resize = false;
487            }
488        }
489        return true;
490    }
491    
492    bool DimRegionChooser::is_in_resize_zone(double x, double y)
493    {
494        if (region && y < nbDimensions * h && x >= label_width && x < w) {
495            int ydim = int(y / h);
496            int dim;
497            int bitpos = 0;
498            for (dim = 0 ; dim < region->Dimensions ; dim++) {
499                if (region->pDimensionDefinitions[dim].bits == 0) continue;
500                if (ydim == 0) break;
501                ydim--;
502                bitpos += region->pDimensionDefinitions[dim].bits;
503            }
504            int nbZones = region->pDimensionDefinitions[dim].zones;
505    
506            int c = 0;
507            if (dimregno >= 0) {
508                int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);
509                c = dimregno & mask; // mask away this dimension
510            }
511            bool customsplits =
512                ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&
513                  region->pDimensionRegions[c]->DimensionUpperLimits[dim]) ||
514                 (region->pDimensionDefinitions[dim].dimension == gig::dimension_velocity &&
515                  region->pDimensionRegions[c]->VelocityUpperLimit));
516    
517            if (customsplits) {
518                int prev_limit = 0;
519                for (int j = 0 ; j < nbZones - 1 ; j++) {
520                    gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
521                    int upperLimit = d->DimensionUpperLimits[dim];
522                    if (!upperLimit) upperLimit = d->VelocityUpperLimit;
523                    int limit = upperLimit + 1;
524                    int limitx = int((w - label_width - 1) * limit / 128.0 + 0.5) + label_width;
525    
526                    if (x <= limitx - 2) break;
527                    if (x <= limitx + 2) {
528                        resize.dimension = dim;
529                        resize.offset = j << bitpos;
530                        resize.pos = limit;
531                        resize.min = prev_limit;
532    
533                        int dr = (dimregno >> bitpos) &
534                            ((1 << region->pDimensionDefinitions[dim].bits) - 1);
535                        resize.selected = dr == j ? resize.left :
536                            dr == j + 1 ? resize.right : resize.none;
537    
538                        j++;
539                        gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
540                        int upperLimit = d->DimensionUpperLimits[dim];
541                        if (!upperLimit) upperLimit = d->VelocityUpperLimit;
542                        int limit = upperLimit + 1;
543                        resize.max = limit;
544                        return true;
545                    }
546                    prev_limit = limit;
547                }
548            }
549        }
550        return false;
551    }
552    
553  sigc::signal<void> DimRegionChooser::signal_sel_changed()  sigc::signal<void> DimRegionChooser::signal_sel_changed()
554  {  {
555      return sel_changed_signal;      return sel_changed_signal;

Legend:
Removed from v.1089  
changed lines
  Added in v.1092

  ViewVC Help
Powered by ViewVC