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