X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftags%2Fstable%2Fsrc%2Fgtkmm%2Fdock_navigator.cpp;h=62a18c3a98015d2fb611ec8bce4f769177f0401e;hb=47fce282611fbba1044921d22ca887f9b53ad91a;hp=022e6e3cfbc8433f0dfdd80bae89d9ee4059f1f0;hpb=7c6d5426922cb3cda793f688dcd4d534b02765c8;p=synfig.git diff --git a/synfig-studio/tags/stable/src/gtkmm/dock_navigator.cpp b/synfig-studio/tags/stable/src/gtkmm/dock_navigator.cpp index 022e6e3..62a18c3 100644 --- a/synfig-studio/tags/stable/src/gtkmm/dock_navigator.cpp +++ b/synfig-studio/tags/stable/src/gtkmm/dock_navigator.cpp @@ -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 */ /* ========================================================================= */ @@ -33,22 +35,24 @@ #include "workarea.h" #include -#include -#include -#include -#include +#include +#include +#include +#include #include #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 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,53 @@ 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*/) { +#ifdef SINGLE_THREADED + // 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; +#endif + //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 +311,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 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 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 +339,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 +358,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 +378,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 +390,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 +406,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 +434,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 +447,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 +503,11 @@ studio::Dock_Navigator::~Dock_Navigator() } void studio::Dock_Navigator::changed_canvas_view_vfunc(etl::loose_handle canvas_view) -{ +{ if(canvas_view) - { + { Widget *v = canvas_view->get_ext_widget("navview"); - + if(!v) { v = new Widget_NavView(canvas_view); @@ -507,6 +518,6 @@ void studio::Dock_Navigator::changed_canvas_view_vfunc(etl::loose_handle