Removed a bunch more DEBUGPOINT()s.
[synfig.git] / synfig-studio / trunk / src / gtkmm / dock_navigator.cpp
index 022e6e3..7141fa9 100644 (file)
@@ -1,20 +1,22 @@
-/* === S I N F G =========================================================== */
+/* === S Y N F I G ========================================================= */
 /*!    \file dock_navigator.cpp
 **     \brief Dock Nagivator File
 **
-**     $Id: dock_navigator.cpp,v 1.3 2005/01/12 00:31:11 darco Exp $
+**     $Id$
 **
 **     \legal
-**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007 Chris Moore
 **
-**     This software and associated documentation
-**     are CONFIDENTIAL and PROPRIETARY property of
-**     the above-mentioned copyright holder.
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
 **
-**     You may not copy, print, publish, or in any
-**     other way distribute this software without
-**     a prior written agreement with
-**     the copyright holder.
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
 **     \endlegal
 */
 /* ========================================================================= */
 #include "workarea.h"
 
 #include <cassert>
-#include <sinfg/canvas.h>
-#include <sinfg/context.h>
-#include <sinfg/target_scanline.h>
-#include <sinfg/surface.h>
+#include <synfig/canvas.h>
+#include <synfig/context.h>
+#include <synfig/target_scanline.h>
+#include <synfig/surface.h>
 
 #include <gtkmm/separator.h>
 
 #include "asyncrenderer.h"
 
+#include "general.h"
+
 #endif
 
 /* === U S I N G =========================================================== */
 
 using namespace std;
 using namespace etl;
-using namespace sinfg;
+using namespace synfig;
 
 /* === M A C R O S ========================================================= */
 
@@ -64,48 +68,49 @@ const double log_10_2 = log(2.0);
 studio::Widget_NavView::Widget_NavView(CanvasView::LooseHandle cv)
 :canvview(cv),
 adj_zoom(0,-4,4,1,2),
-surface(new sinfg::Surface)
+scrolling(false),
+surface(new synfig::Surface)
 {
        attach(drawto,0,4,0,1);
-       
+
        attach(*manage(new Gtk::HSeparator),0,4,1,2,Gtk::SHRINK|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
-       
+
        //zooming stuff
        attach(zoom_print,0,1,2,3,Gtk::SHRINK|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
        zoom_print.set_size_request(40,-1);
-       
+
        Gtk::HScale *s = manage(new Gtk::HScale(adj_zoom));
        s->set_draw_value(false);
        //s->set_update_policy(Gtk::UPDATE_DELAYED);
        //s->signal_event().connect(sigc::mem_fun(*this,&Dock_Navigator::on_scroll_event));
        attach(*s,1,4,2,3,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
-               
+
        show_all();
-       
+
        adj_zoom.signal_value_changed().connect(sigc::mem_fun(*this,&Widget_NavView::on_number_modify));
-       
+
        if(cv)
        {
                drawto.signal_expose_event().connect(sigc::mem_fun(*this,&Widget_NavView::on_expose_draw));
                drawto.signal_event().connect(sigc::mem_fun(*this,&Widget_NavView::on_mouse_event));
-               
+
                drawto.add_events(Gdk::BUTTON_MOTION_MASK|Gdk::BUTTON_PRESS_MASK);
-               
+
                //get_canvas_view()->canvas_interface()->signal_dirty_preview()
                //                              .connect(sigc::mem_fun(*this,&Widget_NavView::on_dirty_preview));
                get_canvas_view()->work_area->signal_rendering()
                                                .connect(sigc::mem_fun(*this,&Widget_NavView::on_dirty_preview));
-               
+
                get_canvas_view()->work_area->signal_view_window_changed()
                                                .connect(sigc::mem_fun(*this,&Widget_NavView::on_workarea_view_change));
-               
+
                //update with this canvas' view
                on_workarea_view_change();
-                               
+
                dirty = true;
                queue_draw();
        }
-       
+
        adj_zoom.set_value(0);
 }
 
@@ -123,49 +128,49 @@ void studio::Widget_NavView::on_start_render()
 {
        if(dirty)
        {
-               //sinfg::warning("Nav: Starting render");
-               //sinfg::warning("Nav: Rendering canvas");
+               //synfig::warning("Nav: Starting render");
+               //synfig::warning("Nav: Rendering canvas");
                etl::handle<Target_Scanline>    targ = surface_target(surface.get());
-               
+
                targ->set_canvas(get_canvas_view()->get_canvas());
                targ->set_remove_alpha();
                targ->set_avoid_time_sync();
                targ->set_quality(get_canvas_view()->get_work_area()->get_quality());
-               //sinfg::info("Set the quality level to: %d", get_canvas_view()->get_work_area()->get_quality());
-               
+               //synfig::info("Set the quality level to: %d", get_canvas_view()->get_work_area()->get_quality());
+
                //this should set it to render a single frame
                RendDesc        r = get_canvas_view()->get_canvas()->rend_desc();
                r.set_time(get_canvas_view()->canvas_interface()->get_time());
-               
+
                //this changes the size of the canvas to the closest thing we can find
                int sw = r.get_w(), sh = r.get_h();
-               
-               //sinfg::warning("Nav: source image is %d x %d", sw,sh);
-               
+
+               //synfig::warning("Nav: source image is %d x %d", sw,sh);
+
                //resize so largest dimension is 128
                int dw = sw > sh ? 128 : sw*128/sh,
                        dh = sh > sw ? 128 : sh*128/sw;
-               
-               //sinfg::warning("Nav: dest image is %d x %d", dw,dh);
-               
+
+               //synfig::warning("Nav: dest image is %d x %d", dw,dh);
+
                r.set_w(dw);
                r.set_h(dh);
 
                //get the pw and ph
                //float pw = r.get_pw();
                //float ph = r.get_ph();
-               
-               //sinfg::warning("Nav: pixel size is %f x %f", pw,ph);
-               
+
+               //synfig::warning("Nav: pixel size is %f x %f", pw,ph);
+
                //this renders that single frame
                targ->set_rend_desc(&r);
-               
-               //sinfg::warning("Nav: Building async renderer and starting it...");
-               
+
+               //synfig::warning("Nav: Building async renderer and starting it...");
+
                renderer = new AsyncRenderer(targ);
                renderer->signal_success().connect(sigc::mem_fun(*this,&Widget_NavView::on_finish_render));
-               renderer->start();
                dirty = false;
+               renderer->start();
        }
 }
 
@@ -173,42 +178,41 @@ void studio::Widget_NavView::on_finish_render()
 {
        //convert it into our pixmap
        PixelFormat pf(PF_RGB);
-       
-       //sinfg::warning("Nav: It hath succeeded!!!");
-       
+
+       //synfig::warning("Nav: It hath succeeded!!!");
+
        //assert(renderer && renderer->has_success());
-       DEBUGPOINT();
-       //sinfg::warning("Nav: now we know it really succeeded");
+       //synfig::warning("Nav: now we know it really succeeded");
        if(!*surface)
        {
-               sinfg::warning("dock_navigator: Bad surface");
+               synfig::warning("dock_navigator: Bad surface");
                return;
        }
-       
+
        int w = 0, h = 0;
        int dw = surface->get_w();
        int dh = surface->get_h();
-       
+
        if(prev)
        {
                w = prev->get_width();
                h = prev->get_height();
        }
-       
+
        if(w != dw || h != dh || !prev)
        {
-               const int total_bytes(dw*dh*sinfg::channels(pf));
-               
-               //sinfg::warning("Nav: Updating the pixbuf to be the right size, etc. (%d bytes)", total_bytes);
-               
+               const int total_bytes(dw*dh*synfig::channels(pf));
+
+               //synfig::warning("Nav: Updating the pixbuf to be the right size, etc. (%d bytes)", total_bytes);
+
                prev.clear();
                guint8 *bytes = new guint8[total_bytes]; //24 bits per pixel
-               
+
                //convert into our buffered dataS
-               //sinfg::warning("Nav: converting color format into buffer");
+               //synfig::warning("Nav: converting color format into buffer");
                convert_color_format((unsigned char *)bytes, (*surface)[0], dw*dh, pf, App::gamma);
-               
-               prev = 
+
+               prev =
                Gdk::Pixbuf::create_from_data(
                        bytes,  // pointer to the data
                        Gdk::COLORSPACE_RGB, // the colorspace
@@ -216,21 +220,21 @@ void studio::Widget_NavView::on_finish_render()
                        8, // bits per sample
                        dw,     // width
                        dh,     // height
-                       dw*sinfg::channels(pf), // stride (pitch)
-                       SigC::slot(freegu8)
+                       dw*synfig::channels(pf), // stride (pitch)
+                       sigc::ptr_fun(freegu8)
                );
        }
        else
        {
-               //sinfg::warning("Nav: Don't need to resize");
+               //synfig::warning("Nav: Don't need to resize");
                //convert into our buffered dataS
-               //sinfg::warning("Nav: converting color format into buffer");
+               //synfig::warning("Nav: converting color format into buffer");
                if(prev) //just in case we're stupid
                {
                        convert_color_format((unsigned char *)prev->get_pixels(), (*surface)[0], dw*dh, pf, App::gamma);
                }
        }
-       queue_draw();   
+       queue_draw();
 }
 
 /*     zoom slider is on exponential scale
@@ -253,46 +257,51 @@ static double zoom_to_unit(double f)
        }else return -999999.0;
 }
 
-bool studio::Widget_NavView::on_expose_draw(GdkEventExpose *exp)
+bool studio::Widget_NavView::on_expose_draw(GdkEventExpose */*exp*/)
 {
+       // don't redraw if the previous redraw is still running single-threaded
+       // or we end up destroying the renderer that's rendering it
+       if (App::single_threaded && renderer && renderer->updating)
+               return false;
+
        //print out the zoom
        //HACK kind of...
        //zoom_print.set_text(strprintf("%.1f%%",100*unit_to_zoom(adj_zoom.get_value())));
-       
+
        //draw the good stuff
        on_start_render();
-       
+
        //if we've got a preview etc. display it...
        if(get_canvas_view() && prev)
        {
                //axis transform from units to pixel coords
                float xaxis = 0, yaxis = 0;
-               
+
                int canvw = get_canvas_view()->get_canvas()->rend_desc().get_w();
                //int canvh = get_canvas_view()->get_canvas()->rend_desc().get_h();
-               
+
                float pw = get_canvas_view()->get_canvas()->rend_desc().get_pw();
                float ph = get_canvas_view()->get_canvas()->rend_desc().get_ph();
-               
+
                int w = prev->get_width();
                int h = prev->get_height();
-                               
+
                //scale up/down to the nearest pixel ratio...
                //and center in center
                int offx=0, offy=0;
-               
+
                float sx, sy;
                int nw,nh;
-               
+
                sx = drawto.get_width() / (float)w;
                sy = drawto.get_height() / (float)h;
-               
-               //sinfg::warning("Nav redraw: now to scale the bitmap: %.3f x %.3f",sx,sy);
-               
+
+               //synfig::warning("Nav redraw: now to scale the bitmap: %.3f x %.3f",sx,sy);
+
                //round to smallest scale (fit entire thing in window without distortion)
                if(sx > sy) sx = sy;
                //else sy = sx;
-               
+
                //scaling and stuff
                // the point to navpixel space conversion should be:
                //              (navpixels / canvpixels) * (canvpixels / canvsize)
@@ -300,25 +309,25 @@ bool studio::Widget_NavView::on_expose_draw(GdkEventExpose *exp)
                xaxis = sx * w / (float)canvw;
                yaxis = xaxis/ph;
                xaxis /= pw;
-               
+
                //scale to a new pixmap and then copy over to the window
                nw = (int)(w*sx);
                nh = (int)(h*sx);
-               
+
                //must now center to be cool
                offx = (drawto.get_width() - nw)/2;
                offy = (drawto.get_height() - nh)/2;
-               
+
                //trivial escape
                if(nw == 0 || nh == 0)return true;
-                                                       
+
                //draw to drawing area
                Glib::RefPtr<Gdk::GC>   gc = Gdk::GC::create(drawto.get_window());
-               
-               //sinfg::warning("Nav: Scaling pixmap to off (%d,%d) with size (%d,%d)", offx,offy,nw, nh);
+
+               //synfig::warning("Nav: Scaling pixmap to off (%d,%d) with size (%d,%d)", offx,offy,nw, nh);
                Glib::RefPtr<Gdk::Pixbuf> scalepx = prev->scale_simple(nw,nh,Gdk::INTERP_NEAREST);
-               
-               //sinfg::warning("Nav: Drawing scaled bitmap");
+
+               //synfig::warning("Nav: Drawing scaled bitmap");
                drawto.get_window()->draw_pixbuf(
                        gc, //GC
                        scalepx, //pixbuf
@@ -328,18 +337,18 @@ bool studio::Widget_NavView::on_expose_draw(GdkEventExpose *exp)
                        Gdk::RGB_DITHER_MAX, // RgbDither
                        2, 2 // Dither offset X and Y
                );
-                               
+
                //draw fancy red rectangle around focus point
                const Point &wtl = get_canvas_view()->work_area->get_window_tl(),
                                        &wbr = get_canvas_view()->work_area->get_window_br();
-               
+
                gc->set_rgb_fg_color(Gdk::Color("#ff0000"));
                gc->set_line_attributes(2,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
-               
+
                //it must be clamped to the drawing area though
                int l=0,rw=0,t=0,rh=0;
                const Point fp = -get_canvas_view()->work_area->get_focus_point();
-               
+
                //get focus point in normal space
                rw = (int)(abs((wtl[0]-wbr[0])*xaxis));
                rh = (int)(abs((wtl[1]-wbr[1])*yaxis));
@@ -347,16 +356,16 @@ bool studio::Widget_NavView::on_expose_draw(GdkEventExpose *exp)
                //transform into pixel space
                l = (int)(drawto.get_width()/2 + fp[0]*xaxis - rw/2);
                t = (int)(drawto.get_height()/2 + fp[1]*yaxis - rh/2);
-       
+
                //coord system:
                // tl : (offx,offy)
                // axis multipliers = xaxis,yaxis
-               //sinfg::warning("Nav: tl (%f,%f), br (%f,%f)", wtl[0],wtl[1],wbr[0],wbr[1]);
-               //sinfg::warning("Nav: tl (%f,%f), br (%f,%f)", wtl[0],wtl[1],wbr[0],wbr[1]);
-               //sinfg::warning("Nav: Drawing Rectangle (%d,%d) with dim (%d,%d)", l,t,rw,rh);
+               //synfig::warning("Nav: tl (%f,%f), br (%f,%f)", wtl[0],wtl[1],wbr[0],wbr[1]);
+               //synfig::warning("Nav: tl (%f,%f), br (%f,%f)", wtl[0],wtl[1],wbr[0],wbr[1]);
+               //synfig::warning("Nav: Drawing Rectangle (%d,%d) with dim (%d,%d)", l,t,rw,rh);
                drawto.get_window()->draw_rectangle(gc,false,l,t,rw,rh);
        }
-       
+
        return false; //draw everything else too
 }
 
@@ -367,11 +376,11 @@ void studio::Widget_NavView::on_dirty_preview()
 }
 
 bool studio::Widget_NavView::on_scroll_event(GdkEvent *event)
-{      
+{
        if(get_canvas_view() && get_canvas_view()->get_work_area())
        {
                double z = unit_to_zoom(adj_zoom.get_value());
-               
+
                switch(event->type)
                {
                        case GDK_BUTTON_PRESS:
@@ -379,12 +388,12 @@ bool studio::Widget_NavView::on_scroll_event(GdkEvent *event)
                                if(event->button.button == 1)
                                {
                                        scrolling = true;
-                                       get_canvas_view()->get_work_area()->set_zoom(z);                                        
+                                       get_canvas_view()->get_work_area()->set_zoom(z);
                                        scrolling = false;
                                }
                                break;
                        }
-                       
+
                        case GDK_MOTION_NOTIFY:
                        {
                                if(Gdk::ModifierType(event->motion.state) & Gdk::BUTTON1_MASK)
@@ -395,21 +404,21 @@ bool studio::Widget_NavView::on_scroll_event(GdkEvent *event)
                                }
                                break;
                        }
-                       
+
                        default:
                                break;
                }
        }
-       
+
        return false;
 }
 
 void studio::Widget_NavView::on_number_modify()
 {
        double z = unit_to_zoom(adj_zoom.get_value());
-       zoom_print.set_text(strprintf("%.1f%%",z*100.0));       
-       //sinfg::warning("Updating zoom to %f",adj_zoom.get_value());
-       
+       zoom_print.set_text(strprintf("%.1f%%",z*100.0));
+       //synfig::warning("Updating zoom to %f",adj_zoom.get_value());
+
        if(get_canvas_view() && z != get_canvas_view()->get_work_area()->get_zoom())
        {
                scrolling = true;
@@ -423,7 +432,7 @@ void studio::Widget_NavView::on_workarea_view_change()
        double wz = get_canvas_view()->get_work_area()->get_zoom();
        double z = zoom_to_unit(wz);
 
-       //sinfg::warning("Updating zoom to %f -> %f",wz,z);
+       //synfig::warning("Updating zoom to %f -> %f",wz,z);
        if(!scrolling && z != adj_zoom.get_value())
        {
                adj_zoom.set_value(z);
@@ -436,53 +445,53 @@ bool studio::Widget_NavView::on_mouse_event(GdkEvent * e)
 {
        Point p;
        bool    setpos = false;
-               
+
        if(e->type == GDK_BUTTON_PRESS && e->button.button == 1)
        {
                p[0] = e->button.x - drawto.get_width()/2;
                p[1] = e->button.y - drawto.get_height()/2;
-               
+
                setpos = true;
        }
-       
+
        if(e->type == GDK_MOTION_NOTIFY && (Gdk::ModifierType(e->motion.state) & Gdk::BUTTON1_MASK))
-       {               
+       {
                p[0] = e->motion.x - drawto.get_width()/2;
-               p[1] = e->motion.y - drawto.get_height()/2;     
-               
+               p[1] = e->motion.y - drawto.get_height()/2;
+
                setpos = true;
        }
-       
+
        if(setpos && prev && get_canvas_view())
        {
                const Point &tl = get_canvas_view()->get_canvas()->rend_desc().get_tl();
                const Point &br = get_canvas_view()->get_canvas()->rend_desc().get_br();
-               
+
                float max = abs((br[0]-tl[0]) / drawto.get_width());
-               
-               if((prev->get_width() / drawto.get_width()) < (prev->get_height() / drawto.get_height()))
+
+               if((float(prev->get_width()) / drawto.get_width()) < (float(prev->get_height()) / drawto.get_height()))
                        max = abs((br[1]-tl[1]) / drawto.get_height());
-               
+
                float signx = (br[0]-tl[0]) < 0 ? -1 : 1;
                float signy = (br[1]-tl[1]) < 0 ? -1 : 1;
-               
+
                Point pos;
-               
+
                pos[0] = p[0] * max * signx;
                pos[1] = p[1] * max * signy;
-               
+
                get_canvas_view()->get_work_area()->set_focus_point(-pos);
-               
+
                return true;
        }
-       
+
        return false;
 }
 
 //Navigator Dock Definitions
 
 studio::Dock_Navigator::Dock_Navigator()
-:Dock_CanvasSpecific("navigator",_("Navigator"),Gtk::StockID("sinfg-navigator"))
+:Dock_CanvasSpecific("navigator",_("Navigator"),Gtk::StockID("synfig-navigator"))
 {
        add(dummy);
 }
@@ -492,11 +501,11 @@ studio::Dock_Navigator::~Dock_Navigator()
 }
 
 void studio::Dock_Navigator::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
-{      
+{
        if(canvas_view)
-       {               
+       {
                Widget *v = canvas_view->get_ext_widget("navview");
-               
+
                if(!v)
                {
                        v = new Widget_NavView(canvas_view);
@@ -507,6 +516,6 @@ void studio::Dock_Navigator::changed_canvas_view_vfunc(etl::loose_handle<CanvasV
        }else
        {
                clear_previous();
-               //add(dummy);                   
+               //add(dummy);
        }
 }