Remove spaces and tabs at end of lines.
[synfig.git] / synfig-studio / trunk / src / gtkmm / workarea.cpp
index 8924d12..9038bb1 100644 (file)
@@ -6,8 +6,8 @@
 **
 **     \legal
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright 2006 Yue Shi Lai
-**     Copyright (c) 2007 Chris Moore
+**     Copyright (c) 2006 Yue Shi Lai
+**     Copyright (c) 2007, 2008 Chris Moore
 **
 **     This package is free software; you can redistribute it and/or
 **     modify it under the terms of the GNU General Public License as
@@ -171,8 +171,7 @@ public:
                set_clipping(true);
                if(low_res)
                {
-
-                       int div = 1 << workarea->get_lowrespixel();
+                       int div = workarea->get_low_res_pixel_size();
                        set_tile_w(workarea->tile_w/div);
                        set_tile_h(workarea->tile_h/div);
                }
@@ -195,7 +194,7 @@ public:
                assert(workarea);
                newdesc->set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
                if(low_res) {
-                       int div = 1 << workarea->get_lowrespixel();
+                       int div = workarea->get_low_res_pixel_size();
                        newdesc->set_wh(w/div,h/div);
                }
                else
@@ -309,7 +308,10 @@ public:
                        int w(get_tile_w());
                        int h(get_tile_h());
                        int x(surface.get_w()*surface.get_h());
-                       //if(low_res) { w/=2,h/=2; }
+                       //if(low_res) {
+                       //      int div = workarea->get_low_res_pixel_size();
+                       //      w/=div,h/=div;
+                       //}
                        Color dark(0.6,0.6,0.6);
                        Color lite(0.8,0.8,0.8);
                        for(int i=0;i<x;i++)
@@ -349,8 +351,7 @@ public:
                if(low_res)
                {
                        // We need to scale up
-
-                       int div = 1 << workarea->get_lowrespixel();
+                       int div = workarea->get_low_res_pixel_size();
                        pixbuf=pixbuf->scale_simple(
                                surface.get_w()*div,
                                surface.get_h()*div,
@@ -474,7 +475,10 @@ public:
                assert(workarea);
                newdesc->set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
                if(low_res)
-                       newdesc->set_wh(w/2,h/2);
+               {
+                       int div = workarea->get_low_res_pixel_size();
+                       newdesc->set_wh(w/div,h/div);
+               }
                else
                        newdesc->set_wh(w,h);
 
@@ -550,15 +554,19 @@ public:
                        int w(surface.get_w());
                        //int h(surface.get_h());
                        int x(surface.get_w()*surface.get_h());
-                       //if(low_res) { w/=2,h/=2; }
+                       //if(low_res) {
+                       //      int div = workarea->get_low_res_pixel_size();
+                       //      w/=div,h/=div;
+                       //}
                        Color dark(0.6,0.6,0.6);
                        Color lite(0.8,0.8,0.8);
                        int tw=workarea->tile_w;
                        int th=workarea->tile_h;
                        if(low_res)
                        {
-                               tw/=2;
-                               th/=2;
+                               int div = workarea->get_low_res_pixel_size();
+                               tw/=div;
+                               th/=div;
                        }
                        for(int i=0;i<x;i++)
                                dest=Color2PixelFormat(
@@ -589,9 +597,10 @@ public:
                if(low_res)
                {
                        // We need to scale up
+                       int div = workarea->get_low_res_pixel_size();
                        pixbuf=pixbuf->scale_simple(
-                               surface.get_w()*2,
-                               surface.get_h()*2,
+                               surface.get_w()*div,
+                               surface.get_h()*div,
                                Gdk::INTERP_NEAREST
                        );
                }
@@ -655,7 +664,7 @@ WorkArea::WorkArea(etl::loose_handle<synfigapp::CanvasInterface> canvas_interfac
        render_idle_func_id=0;
        zoom=prev_zoom=1.0;
        quality=10;
-       lowrespixel=1;
+       low_res_pixel_size=2;
        rendering=false;
        canceled_=false;
        low_resolution=true;
@@ -819,18 +828,22 @@ WorkArea::~WorkArea()
                render_idle_func_id=0;
 }
 
+#ifdef SINGLE_THREADED
 bool
 WorkArea::get_updating()const
 {
        return App::single_threaded && async_renderer && async_renderer->updating;
 }
+#endif
 
+#ifdef SINGLE_THREADED
 void
 WorkArea::stop_updating(bool cancel)
 {
        async_renderer->stop();
        if (cancel) canceled_=true;
 }
+#endif
 
 void
 WorkArea::save_meta_data()
@@ -1155,7 +1168,7 @@ WorkArea::on_key_press_event(GdkEventKey* event)
                        break;
        }
 
-       synfigapp::Action::PassiveGrouper grouper(instance.get(),"Nudge");
+       synfigapp::Action::PassiveGrouper grouper(instance.get(),_("Nudge"));
 
        // Grid snap does not apply to nudging
        bool grid_snap_holder(get_grid_snap());
@@ -1190,8 +1203,6 @@ WorkArea::on_drawing_area_event(GdkEvent *event)
        bool is_mouse(false);
        Gdk::ModifierType modifier(Gdk::ModifierType(0));
 
-       drawing_area->grab_focus();
-
        // Handle input stuff
        if(
                event->any.type==GDK_MOTION_NOTIFY ||
@@ -1211,6 +1222,7 @@ WorkArea::on_drawing_area_event(GdkEvent *event)
                {
                        device=event->button.device;
                        modifier=Gdk::ModifierType(event->button.state);
+                       drawing_area->grab_focus();
                }
 
                // Make sure we recognize the device
@@ -1339,8 +1351,11 @@ WorkArea::on_drawing_area_event(GdkEvent *event)
 
 
                        selected_bezier=find_bezier(mouse_pos,radius,&bezier_click_pos);
-                       if(duck && duck->get_editable())
+                       if(duck)
                        {
+                               if (!duck->get_editable())
+                                       return true;
+
                                //get_selected_duck()->signal_user_click(0)();
                                //if(clicked_duck)clicked_duck->signal_user_click(0)();
 
@@ -1356,15 +1371,19 @@ WorkArea::on_drawing_area_event(GdkEvent *event)
                                                // if the tangent isn't split, then split it
                                                if (!((*(parent_value_node->get_link("split")))(get_time()).get(bool())))
                                                {
-                                                       get_canvas_view()->canvas_interface()->
+                                                       if (get_canvas_view()->canvas_interface()->
                                                                change_value(synfigapp::ValueDesc(parent_value_node,
                                                                                                                                  parent_value_node->get_link_index_from_name("split")),
-                                                                                        true);
-                                                       // rebuild the ducks from scratch, so the tangents ducks aren't connected
-                                                       get_canvas_view()->rebuild_ducks();
-
-                                                       // reprocess the mouse click
-                                                       return on_drawing_area_event(event);
+                                                                                        true))
+                                                       {
+                                                               // rebuild the ducks from scratch, so the tangents ducks aren't connected
+                                                               get_canvas_view()->rebuild_ducks();
+
+                                                               // reprocess the mouse click
+                                                               return on_drawing_area_event(event);
+                                                       }
+                                                       else
+                                                               return true;
                                                }
                                        } else {
                                                // I don't know how to access the vertex from the tangent duck when originally drawing the bline in the bline tool
@@ -1609,7 +1628,7 @@ WorkArea::on_drawing_area_event(GdkEvent *event)
                else
                if(dragging==DRAG_DUCK)
                {
-                       synfigapp::Action::PassiveGrouper grouper(instance.get(),"Move");
+                       synfigapp::Action::PassiveGrouper grouper(instance.get(),_("Move"));
                        dragging=DRAG_NONE;
                        //translate_selected_ducks(mouse_pos);
                        set_axis_lock(false);
@@ -1985,8 +2004,7 @@ WorkArea::next_unrendered_tile(int refreshes)const
                x(focus_point[0]/pw+drawing_area->get_width()/2-w/2),
                y(focus_point[1]/ph+drawing_area->get_height()/2-h/2);
 
-
-       int div = 1 << lowrespixel;
+       int div = low_res_pixel_size;
        const int width_in_tiles(w/tile_w+((low_resolution?((w/div)%(tile_w/div)):(w%tile_w))?1:0));
        const int height_in_tiles(h/tile_h+(h%tile_h?1:0));
 
@@ -2119,8 +2137,6 @@ WorkArea::refresh(GdkEventExpose*event)
                drawing_frame->unset_bg(Gtk::STATE_NORMAL);
 #endif
 
-       previous_focus=get_focus_point();
-
        return true;
 }
 
@@ -2154,17 +2170,14 @@ WorkArea::set_quality(int x)
 }
 
 void
-WorkArea::set_lowrespixel(int x)
+WorkArea::set_low_res_pixel_size(int x)
 {
-       if(x==lowrespixel)
+       if(x==low_res_pixel_size)
                return;
-       lowrespixel=x;
+       low_res_pixel_size=x;
        queue_render_preview();
 }
 
-
-
-
 namespace studio
 {
 class WorkAreaProgress : public synfig::ProgressCallback
@@ -2209,12 +2222,14 @@ public:
 bool
 studio::WorkArea::async_update_preview()
 {
+#ifdef SINGLE_THREADED
        if (get_updating())
        {
                stop_updating();
                queue_render_preview();
                return false;
        }
+#endif
 
        async_renderer=0;
 
@@ -2251,6 +2266,11 @@ studio::WorkArea::async_update_preview()
        int w=(int)(desc.get_w()*zoom);
        int h=(int)(desc.get_h()*zoom);
 
+       // ensure that the size we draw is at least one pixel in each dimension
+       int min_size = low_resolution ? low_res_pixel_size : 1;
+       if (w < min_size) w = min_size;
+       if (h < min_size) h = min_size;
+
        // Setup the description parameters
        desc.set_antialias(1);
        desc.set_time(cur_time);
@@ -2261,9 +2281,9 @@ studio::WorkArea::async_update_preview()
        handle<Target> target;
 
        // if we have lots of pixels to render and the tile renderer isn't disabled, use it
-       int div = 1 << lowrespixel;
-       if(w*h>(low_resolution?480*270:480*270/div) &&
-          !getenv("SYNFIG_DISABLE_TILE_RENDER"))
+       int div;
+       div = low_resolution ? low_res_pixel_size : 1;
+       if ((w*h > 240*div*135*div && !getenv("SYNFIG_DISABLE_TILE_RENDER")) || getenv("SYNFIG_FORCE_TILE_RENDER"))
        {
                // do a tile render
                handle<WorkAreaTarget> trgt(new class WorkAreaTarget(this,w,h));
@@ -2525,7 +2545,7 @@ WorkArea::queue_scroll()
                        drawing_area->queue_draw_area(      0, 0,       1, maxy);
                        drawing_area->queue_draw_area(maxx-dx, 0, maxx-dx, maxy);
                }
-               else if (dx < 0) 
+               else if (dx < 0)
                {
                        drawing_area->queue_draw_area(   maxx, 0,    maxx, maxy);
                        drawing_area->queue_draw_area(    -dx, 0,     -dx, maxy);
@@ -2535,7 +2555,7 @@ WorkArea::queue_scroll()
                        drawing_area->queue_draw_area(0,       0, maxx,       1);
                        drawing_area->queue_draw_area(0, maxy-dy, maxx, maxy-dy);
                }
-               else if (dy < 0) 
+               else if (dy < 0)
                {
                        drawing_area->queue_draw_area(0,    maxy, maxx,    maxy);
                        drawing_area->queue_draw_area(0,     -dy, maxx,     -dy);
@@ -2561,20 +2581,25 @@ studio::WorkArea::zoom_out()
 void
 studio::WorkArea::zoom_fit()
 {
-       // This really doesn't zoom to fit. Bug.
-       zoom_norm();
+       float new_zoom(min(drawing_area->get_width() * zoom / w,
+                                          drawing_area->get_height() * zoom / h) * 0.995);
+       if (zoom / new_zoom > 0.995 && new_zoom / zoom > 0.995)
+       {
+               set_zoom(prev_zoom);
+               return set_focus_point(previous_focus);
+       }
+       previous_focus = get_focus_point();
+       prev_zoom = zoom;
+       set_zoom(new_zoom);
+       set_focus_point(Point(0,0));
 }
 
 void
 studio::WorkArea::zoom_norm()
 {
-       if(zoom==1.0)
-               set_zoom(prev_zoom);
-       else
-       {
-               prev_zoom=zoom;
-               set_zoom(1.0f);
-       }
+       if (zoom == 1.0) return set_zoom(prev_zoom);
+       prev_zoom = zoom;
+       set_zoom(1.0f);
 }
 
 gboolean
@@ -2625,7 +2650,7 @@ studio::WorkArea::queue_render_preview()
                //synfig::info("queue_render_preview(): (re)queuing...");
                //render_idle_func_id=g_idle_add_full(G_PRIORITY_DEFAULT,__render_preview,this,NULL);
                render_idle_func_id=g_timeout_add_full(
-                       G_PRIORITY_DEFAULT,     // priority - 
+                       G_PRIORITY_DEFAULT,     // priority -
                        queue_time,                     // interval - the time between calls to the function, in milliseconds (1/1000ths of a second)
                        __render_preview,       // function - function to call
                        this,                           // data     - data to pass to function