Remove .gitignore do nothing is ignored.
[synfig.git] / synfig-studio / trunk / src / gtkmm / widget_timeslider.cpp
index d935b54..ed5d63c 100644 (file)
@@ -505,12 +505,30 @@ bool Widget_Timeslider::redraw(bool /*doublebuffer*/)
                iter = next;
 
        scale = *iter;
-       if (iter != ranges.begin()) iter--;
-       if (iter != ranges.begin()) iter--;
-       if (iter != ranges.begin()) iter--;
 
        // subdivide into this many tick marks (8 or less)
-       const int subdiv = round_to_int(scale / *iter);
+       int subdiv = round_to_int(scale * ifps);
+
+       if (subdiv > 8)
+       {
+               const int ideal = subdiv;
+
+               // find a number of tick marks that nicely divides the scale
+               // (5 minutes divided by 6 is 50s, but that's not 'nice' -
+               //  5 ticks of 1m each is much simpler than 6 ticks of 50s)
+               for (subdiv = 8; subdiv > 0; subdiv--)
+                       if ((ideal <= ifps*2       && (ideal % (subdiv           )) == 0) ||
+                               (ideal <= ifps*2*60    && (ideal % (subdiv*ifps      )) == 0) ||
+                               (ideal <= ifps*2*60*60 && (ideal % (subdiv*ifps*60   )) == 0) ||
+                               (true                  && (ideal % (subdiv*ifps*60*60)) == 0))
+                               break;
+
+               // if we didn't find anything, use 4 ticks
+               if (!subdiv)
+                       subdiv = 4;
+       }
+
+       time_per_tickmark = scale / subdiv;
 
        //get first valid line and its position in pixel space
        double time = 0;
@@ -531,6 +549,7 @@ bool Widget_Timeslider::redraw(bool /*doublebuffer*/)
                double t = (time/scale - floor(time/scale))*subdiv; // the difference from the big mark in 0:1
                //sdindex = (int)floor(t + 0.5); //get how far through the range it is...
                sdindex = round_to_int(t); //get how far through the range it is...
+               if (sdindex == subdiv) sdindex = 0;
 
                //synfig::info("Extracted fr %.2lf -> %d", t, sdindex);
        }
@@ -557,7 +576,17 @@ bool Widget_Timeslider::redraw(bool /*doublebuffer*/)
 
                        //gc->set_rgb_fg_color(Gdk::Color("#000000"));
                        layout->set_text(timecode);
-                       window->draw_layout(gc,xpx+2,heightsmall,layout);
+                       Pango::AttrList attr_list;
+                       // Aproximately a font size of 8 pixels.
+                       // Pango::SCALE = 1024
+                       // create_attr_size waits a number in 1000th of pixels.
+                       // Should be user customizable in the future. Now it is fixed to 10
+                       Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*10));
+                       pango_size.set_start_index(0);
+                       pango_size.set_end_index(64);
+                       attr_list.change(pango_size);
+                       layout->set_attributes(attr_list);
+                       window->draw_layout(gc,xpx+2,0,layout);
                }else
                {
                        window->draw_line(gc,xpx,0,xpx,heightsmall);
@@ -703,50 +732,80 @@ bool Widget_Timeslider::on_scroll_event(GdkEventScroll* event) //for zooming
 
        //we want to zoom in on the time value if control is held down
        if(Gdk::ModifierType(event->state) & Gdk::CONTROL_MASK)
-       {
                center = true;
-       }
 
        switch(event->direction)
        {
                case GDK_SCROLL_UP: //zoom in
-               {
                        zoom_in(center);
-
                        return true;
-               }
+
                case GDK_SCROLL_DOWN: //zoom out
-               {
                        zoom_out(center);
-
                        return true;
-               }
-               
+
                case GDK_SCROLL_RIGHT:
                case GDK_SCROLL_LEFT:
-               {       
+               {
                        double t = adj_timescale->get_value();
+                       double orig_t = t;
                        double start = adj_timescale->get_lower();
                        double end = adj_timescale->get_upper();
-                       /*
-                       FIXME: be more intelligent about how far to scroll
-                       Perhaps it should be based on the tickmarks?
-                       for e.g. 1/4 of a tick mark per scroll event
-                       Obviously this  would need post-rounding to 1/fps
-                       */
-                       double adj = 1.0/fps;
+                       double lower = adj_bounds->get_lower();
+                       double upper = adj_bounds->get_upper();
+                       double adj = time_per_tickmark;
 
                        if( event->direction == GDK_SCROLL_RIGHT )
+                       {
+                               // step forward one tick
                                t += adj;
+
+                               // don't go past the end of time
+                               if (t > upper)
+                                       t = upper;
+
+                               // if we are already in the right half of the slider
+                               if ((t-start)*2 > (end-start))
+                               {
+                                       // if we can't scroll the background left one whole tick, scroll it to the end
+                                       if (end > upper - (t-orig_t))
+                                       {
+                                               adj_timescale->set_lower(upper - (end-start));
+                                               adj_timescale->set_upper(upper);
+                                       }
+                                       // else scroll the background left
+                                       else
+                                       {
+                                               adj_timescale->set_lower(start + (t-orig_t));
+                                               adj_timescale->set_upper(start + (t-orig_t) + (end-start));
+                                       }
+                               }
+                       }
                        else
+                       {
+                               // step backwards one tick
                                t -= adj;
 
-                       if( t < start ){
-                               adj_timescale->set_lower(t);
-                               adj_timescale->set_upper(t+end-start);
-                       } else if( t > end ){ 
-                               adj_timescale->set_upper(t);
-                               adj_timescale->set_lower(t-end+start);
+                               // don't go past the start of time
+                               if (t < lower)
+                                       t = lower;
+
+                               // if we are already in the left half of the slider
+                               if ((t-start)*2 < (end-start))
+                               {
+                                       // if we can't scroll the background right one whole tick, scroll it to the beginning
+                                       if (start < lower + (orig_t-t))
+                                       {
+                                               adj_timescale->set_lower(lower);
+                                               adj_timescale->set_upper(lower + (end-start));
+                                       }
+                                       // else scroll the background right
+                                       else
+                                       {
+                                               adj_timescale->set_lower(start - (orig_t-t));
+                                               adj_timescale->set_upper(start - (orig_t-t) + (end-start));
+                                       }
+                               }
                        }
 
                        if(adj_timescale)
@@ -756,11 +815,8 @@ bool Widget_Timeslider::on_scroll_event(GdkEventScroll* event) //for zooming
                        }
                        return true;
                }
-               
                default:
-               {
                        return false;
-               }
        }
 }