Fix "zoom to fit" so that it centers the fitted canvas on the screen, and always...
[synfig.git] / synfig-studio / trunk / src / gtkmm / workarea.cpp
index 72acd90..97c0a6d 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
@@ -828,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()
@@ -1164,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());
@@ -1199,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 ||
@@ -1220,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
@@ -1348,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)();
 
@@ -1618,7 +1624,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);
@@ -2127,8 +2133,6 @@ WorkArea::refresh(GdkEventExpose*event)
                drawing_frame->unset_bg(Gtk::STATE_NORMAL);
 #endif
 
-       previous_focus=get_focus_point();
-
        return true;
 }
 
@@ -2214,12 +2218,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;
 
@@ -2256,12 +2262,10 @@ 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 a whole number of pixels in each dimension
-       if (low_resolution)
-       {
-               if (w % low_res_pixel_size) w = (w/low_res_pixel_size+1)*low_res_pixel_size;
-               if (h % low_res_pixel_size) h = (h/low_res_pixel_size+1)*low_res_pixel_size;
-       }
+       // 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);
@@ -2573,20 +2577,24 @@ 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));
+       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