minor fix
[synfig.git] / synfig-studio / trunk / src / gtkmm / render.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file render.cpp
3 **      \brief Template File
4 **
5 **      $Id: render.cpp,v 1.2 2005/01/10 08:13:44 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include "render.h"
33 #include "app.h"
34 #include <gtkmm/frame.h>
35 #include <synfig/target_scanline.h>
36 #include <synfig/canvas.h>
37 #include "asyncrenderer.h"
38
39 #endif
40
41 /* === U S I N G =========================================================== */
42
43 using namespace std;
44 using namespace etl;
45 using namespace synfig;
46 using namespace studio;
47
48 /* === M A C R O S ========================================================= */
49
50 /* === G L O B A L S ======================================================= */
51
52 /* === P R O C E D U R E S ================================================= */
53
54 /* === M E T H O D S ======================================================= */
55
56 RenderSettings::RenderSettings(Gtk::Window& parent,handle<synfigapp::CanvasInterface> canvas_interface):
57         Gtk::Dialog(_("Render Settings"),parent,false,true),
58         canvas_interface_(canvas_interface),
59         adjustment_quality(3,0,9),
60         entry_quality(adjustment_quality,1,0),
61         adjustment_antialias(1,1,31),
62         entry_antialias(adjustment_antialias,1,0),
63         toggle_single_frame(_("Use Current Frame"))
64 {
65         widget_rend_desc.show();
66         widget_rend_desc.signal_changed().connect(sigc::mem_fun(*this,&studio::RenderSettings::on_rend_desc_changed));
67         widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
68         
69         canvas_interface->signal_rend_desc_changed().connect(sigc::mem_fun(*this,&RenderSettings::on_rend_desc_changed));
70         
71         menu_target=manage(new class Gtk::Menu());
72
73         menu_target->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Auto"),
74                         sigc::bind(sigc::mem_fun(*this,&RenderSettings::set_target),String())
75                 ));
76
77         synfig::Target::Book::iterator iter;
78         synfig::Target::Book book(synfig::Target::book());
79         
80         for(iter=book.begin();iter!=book.end();iter++)
81         {
82                 menu_target->items().push_back(Gtk::Menu_Helpers::MenuElem(iter->first,
83                         sigc::bind(sigc::mem_fun(*this,&RenderSettings::set_target),iter->first)
84                 ));
85         }
86         optionmenu_target.set_menu(*menu_target);
87
88         optionmenu_target.set_history(0);
89         
90         
91         
92         
93
94         Gtk::Button *choose_button(manage(new class Gtk::Button(Gtk::StockID(_("Choose...")))));
95         choose_button->show();
96         choose_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_choose_pressed));
97         
98         Gtk::Frame *target_frame=manage(new Gtk::Frame(_("Target")));
99         Gtk::Table *target_table=manage(new Gtk::Table(2,2,false));
100         target_frame->add(*target_table);
101         target_table->attach(*manage(new Gtk::Label(_("Filename"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
102         target_table->attach(entry_filename, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
103         target_table->attach(*choose_button, 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
104         target_table->attach(*manage(new Gtk::Label(_("Target"))), 3, 4, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);     
105         target_table->attach(optionmenu_target, 4, 5, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
106         get_vbox()->pack_start(*target_frame);
107
108         toggle_single_frame.signal_toggled().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_single_frame_toggle));
109
110
111         Gtk::Frame *settings_frame=manage(new Gtk::Frame(_("Settings")));
112         Gtk::Table *settings_table=manage(new Gtk::Table(2,2,false));
113         settings_frame->add(*settings_table);
114         settings_table->attach(*manage(new Gtk::Label(_("Quality"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
115         settings_table->attach(entry_quality, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
116         settings_table->attach(*manage(new Gtk::Label(_("Anti-Alias"))), 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);       
117         settings_table->attach(entry_antialias, 3, 4, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
118         settings_table->attach(toggle_single_frame, 4, 5, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
119         get_vbox()->pack_start(*settings_frame);
120         
121         
122
123
124         get_vbox()->pack_start(widget_rend_desc);
125         
126         
127         Gtk::Button *render_button(manage(new class Gtk::Button(Gtk::StockID("Render"))));
128         render_button->show();
129         add_action_widget(*render_button,1);
130         render_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_render_pressed));
131
132         Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))));
133         cancel_button->show();
134         add_action_widget(*cancel_button,0);
135         cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_cancel_pressed));
136
137         //set_default_response(1);
138         
139         set_title(_("Render Settings")+String(" - ")+canvas_interface_->get_canvas()->get_name());
140
141
142         toggle_single_frame.set_active(true);
143         widget_rend_desc.disable_time_section();
144         
145
146         try
147         {
148                 entry_filename.set_text(Glib::build_filename(Glib::get_home_dir(),Glib::ustring("Desktop")+ETL_DIRECTORY_SEPERATOR+Glib::ustring("output.png")));
149         }
150         catch(...)
151         {
152                 synfig::warning("Averted crash!");
153                 entry_filename.set_text("output.png");
154         }
155         
156         get_vbox()->show_all();
157 }
158
159 RenderSettings::~RenderSettings()
160 {
161 }
162
163 void
164 RenderSettings::on_rend_desc_changed()
165 {
166         widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
167 }
168
169 void
170 RenderSettings::set_target(synfig::String name)
171 {
172         target_name=name;
173 }
174
175 void
176 RenderSettings::on_choose_pressed()
177 {
178         String filename=entry_filename.get_text();
179         if(App::dialog_saveas_file("Save Render As",filename))
180                 entry_filename.set_text(filename);
181 }
182
183 void
184 RenderSettings::on_render_pressed()
185 {
186         String filename=entry_filename.get_text();
187         
188         if(filename.empty())
189         {
190                 canvas_interface_->get_ui_interface()->error(_("You must supply a filename!"));
191                 return;
192         }
193
194         // If the target type is not yet defined,
195         // try to figure it out from the outfile.
196         if(target_name.empty())
197         {
198                 try
199                 {
200                         String ext=String(find(filename.begin(),filename.end(),'.')+1,filename.end());
201                         if(Target::ext_book().count(ext))
202                                 target_name=Target::ext_book()[ext];
203                         else
204                                 target_name=ext;
205                 }
206                 catch(std::runtime_error x)
207                 {
208                         canvas_interface_->get_ui_interface()->error(_("Unable to determine proper target from filename."));
209                         return;                 
210                 }
211         }
212
213         if(filename.empty() && target_name!="null")
214         {
215                 canvas_interface_->get_ui_interface()->error(_("A filename is required for this target"));
216                 return;
217         }
218
219         Target::Handle target=Target::create(target_name,filename);
220         if(!target)
221         {
222                 canvas_interface_->get_ui_interface()->error(_("Unable to create target for ")+filename);
223                 return;
224         }
225
226         hide();
227         
228         target->set_canvas(canvas_interface_->get_canvas());
229         RendDesc rend_desc(widget_rend_desc.get_rend_desc());
230         rend_desc.set_antialias((int)adjustment_antialias.get_value());
231         
232         // If we are to only render the current frame
233         if(toggle_single_frame.get_active())
234                 rend_desc.set_time(canvas_interface_->get_time());
235
236         target->set_rend_desc(&rend_desc);
237         target->set_quality((int)adjustment_quality.get_value());
238
239         canvas_interface_->get_ui_interface()->task(_("Rendering ")+filename);
240
241         if(async_renderer)
242         {
243                 async_renderer->stop();
244                 async_renderer.detach();
245         }
246         async_renderer=new AsyncRenderer(target);
247         async_renderer->signal_finished().connect( sigc::mem_fun(*this,&RenderSettings::on_finished));
248         async_renderer->start();
249         /*
250         if(!target->render(canvas_interface_->get_ui_interface().get()))
251         {
252                 canvas_interface_->get_ui_interface()->error(_("Render Failure"));
253                 canvas_interface_->get_ui_interface()->amount_complete(0,10000);
254                 return;
255         }
256         
257         // Success!
258         canvas_interface_->get_ui_interface()->task(filename+_(" rendered sucessfuly"));        
259         canvas_interface_->get_ui_interface()->amount_complete(0,10000);
260         */
261         return; 
262 }
263
264 void
265 RenderSettings::on_finished()
266 {
267         canvas_interface_->get_ui_interface()->task(_("File rendered sucessfuly"));     
268         canvas_interface_->get_ui_interface()->amount_complete(0,10000);
269 }
270         
271 void
272 RenderSettings::on_cancel_pressed()
273 {
274         hide();
275 }
276
277 void
278 RenderSettings::on_single_frame_toggle()
279 {
280         if(toggle_single_frame.get_active())
281                 widget_rend_desc.disable_time_section();
282         else
283                 widget_rend_desc.enable_time_section();
284 }