X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fworkarea.cpp;h=edc989dc64f0e53691e0926ff1f5d7cda3c1e6a9;hb=9459638ad6797b8139f1e9f0715c96076dbf0890;hp=9b77c6c16e916ad2918cb745045b45eb56cce71b;hpb=a27deaf2322fab351ac47cbed699ec3ab8eb198d;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/workarea.cpp b/synfig-studio/trunk/src/gtkmm/workarea.cpp index 9b77c6c..edc989d 100644 --- a/synfig-studio/trunk/src/gtkmm/workarea.cpp +++ b/synfig-studio/trunk/src/gtkmm/workarea.cpp @@ -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 @@ -117,34 +117,38 @@ public: synfig::Mutex mutex; - void set_onion_skin(bool x) + void set_onion_skin(bool x, int *onions) { onionskin=x; Time time(rend_desc().get_time_start()); + if(!onionskin) + return; onion_skin_queue.push_back(time); - //onion_skin_queue.push_back(time-1); - //onion_skin_queue.push_back(time+1); try { - onion_skin_queue.push_back( - get_canvas()->keyframe_list().find_prev( - time - )->get_time() - ); + Time thistime=time; + for(int i=0; ikeyframe_list().find_prev(thistime)->get_time(); + onion_skin_queue.push_back(keytime); + thistime=keytime; + } } catch(...) { } try { - onion_skin_queue.push_back( - get_canvas()->keyframe_list().find_next( - time - )->get_time() - ); + Time thistime=time; + for(int i=0; ikeyframe_list().find_next(thistime)->get_time(); + onion_skin_queue.push_back(keytime); + thistime=keytime; + } } catch(...) { } @@ -171,8 +175,9 @@ public: set_clipping(true); if(low_res) { - set_tile_w(workarea->tile_w/2); - set_tile_h(workarea->tile_h/2); + int div = workarea->get_low_res_pixel_size(); + set_tile_w(workarea->tile_w/div); + set_tile_h(workarea->tile_h/div); } else { @@ -192,8 +197,10 @@ public: { assert(workarea); newdesc->set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN); - if(low_res) - newdesc->set_wh(w/2,h/2); + if(low_res) { + int div = workarea->get_low_res_pixel_size(); + newdesc->set_wh(w/div,h/div); + } else newdesc->set_wh(w,h); @@ -305,7 +312,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;iget_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 ); } @@ -406,36 +417,39 @@ public: std::list onion_skin_queue; - void set_onion_skin(bool x) + void set_onion_skin(bool x, int *onions) { onionskin=x; Time time(rend_desc().get_time_start()); + if(!onionskin) + return; onion_skin_queue.push_back(time); //onion_skin_queue.push_back(time-1); //onion_skin_queue.push_back(time+1); - if(!onionskin) - return; - try { - onion_skin_queue.push_back( - get_canvas()->keyframe_list().find_prev( - time - )->get_time() - ); + Time thistime=time; + for(int i=0; ikeyframe_list().find_prev(thistime)->get_time(); + onion_skin_queue.push_back(keytime); + thistime=keytime; + } } catch(...) { } try { - onion_skin_queue.push_back( - get_canvas()->keyframe_list().find_next( - time - )->get_time() - ); + Time thistime=time; + for(int i=0; ikeyframe_list().find_next(thistime)->get_time(); + onion_skin_queue.push_back(keytime); + thistime=keytime; + } } catch(...) { } @@ -468,7 +482,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); @@ -544,15 +561,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;iget_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 ); } @@ -649,6 +671,7 @@ WorkArea::WorkArea(etl::loose_handle canvas_interfac render_idle_func_id=0; zoom=prev_zoom=1.0; quality=10; + low_res_pixel_size=2; rendering=false; canceled_=false; low_resolution=true; @@ -656,6 +679,8 @@ WorkArea::WorkArea(etl::loose_handle canvas_interfac ph=0.001; last_focus_point=Point(0,0); onion_skin=false; + onion_skins[0]=0; + onion_skins[1]=0; queued=false; dirty_trap_enabled=false; solid_lines=true; @@ -812,18 +837,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() @@ -999,6 +1028,14 @@ WorkArea::get_onion_skin()const return onion_skin; } +void WorkArea::set_onion_skins(int *onions) +{ + onion_skins[0]=onions[0]; + onion_skins[1]=onions[1]; + if(onion_skin) + queue_render_preview(); +} + void WorkArea::enable_grid() { @@ -1148,7 +1185,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()); @@ -1183,8 +1220,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 || @@ -1204,6 +1239,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 @@ -1332,8 +1368,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)(); @@ -1349,15 +1388,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 @@ -1602,7 +1645,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); @@ -1978,7 +2021,8 @@ 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); - const int width_in_tiles(w/tile_w+((low_resolution?((w/2)%(tile_w/2)):(w%tile_w))?1:0)); + 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)); int @@ -2110,8 +2154,6 @@ WorkArea::refresh(GdkEventExpose*event) drawing_frame->unset_bg(Gtk::STATE_NORMAL); #endif - previous_focus=get_focus_point(); - return true; } @@ -2144,6 +2186,14 @@ WorkArea::set_quality(int x) queue_render_preview(); } +void +WorkArea::set_low_res_pixel_size(int x) +{ + if(x==low_res_pixel_size) + return; + low_res_pixel_size=x; + queue_render_preview(); +} namespace studio { @@ -2189,12 +2239,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; @@ -2231,6 +2283,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); @@ -2241,14 +2298,15 @@ studio::WorkArea::async_update_preview() handle target; // if we have lots of pixels to render and the tile renderer isn't disabled, use it - if(w*h>(low_resolution?480*270:480*270/2) && - !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 trgt(new class WorkAreaTarget(this,w,h)); trgt->set_rend_desc(&desc); - trgt->set_onion_skin(get_onion_skin()); + trgt->set_onion_skin(get_onion_skin(), onion_skins); target=trgt; } else @@ -2257,7 +2315,7 @@ studio::WorkArea::async_update_preview() handle trgt(new class WorkAreaTarget_Full(this,w,h)); trgt->set_rend_desc(&desc); - trgt->set_onion_skin(get_onion_skin()); + trgt->set_onion_skin(get_onion_skin(), onion_skins); target=trgt; } @@ -2504,7 +2562,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); @@ -2514,7 +2572,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); @@ -2540,20 +2598,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 @@ -2604,7 +2667,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