1 /* === S Y N F I G ========================================================= */
2 /*! \file gtkmm/render.cpp
3 ** \brief Template File
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
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.
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.
21 /* ========================================================================= */
23 /* === H E A D E R S ======================================================= */
34 #include <gtkmm/frame.h>
35 #include <gtkmm/alignment.h>
36 #include <synfig/target_scanline.h>
37 #include <synfig/canvas.h>
38 #include "asyncrenderer.h"
42 /* === U S I N G =========================================================== */
46 using namespace synfig;
47 using namespace studio;
49 /* === M A C R O S ========================================================= */
51 /* === G L O B A L S ======================================================= */
53 /* === P R O C E D U R E S ================================================= */
55 /* === M E T H O D S ======================================================= */
57 RenderSettings::RenderSettings(Gtk::Window& parent,handle<synfigapp::CanvasInterface> canvas_interface):
58 Gtk::Dialog(_("Render Settings"),parent,false,true),
59 canvas_interface_(canvas_interface),
60 adjustment_quality(3,0,9),
61 entry_quality(adjustment_quality,1,0),
62 adjustment_antialias(1,1,31),
63 entry_antialias(adjustment_antialias,1,0),
64 toggle_single_frame(_("Use _current frame"), true)
66 widget_rend_desc.show();
67 widget_rend_desc.signal_changed().connect(sigc::mem_fun(*this,&studio::RenderSettings::on_rend_desc_changed));
68 widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
70 canvas_interface->signal_rend_desc_changed().connect(sigc::mem_fun(*this,&RenderSettings::on_rend_desc_changed));
72 menu_target=manage(new class Gtk::Menu());
74 menu_target->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Auto"),
75 sigc::bind(sigc::mem_fun(*this,&RenderSettings::set_target),String())
78 synfig::Target::Book::iterator iter;
79 synfig::Target::Book book(synfig::Target::book());
81 for(iter=book.begin();iter!=book.end();iter++)
83 menu_target->items().push_back(Gtk::Menu_Helpers::MenuElem(iter->first,
84 sigc::bind(sigc::mem_fun(*this,&RenderSettings::set_target),iter->first)
87 optionmenu_target.set_menu(*menu_target);
89 optionmenu_target.set_history(0);
91 Gtk::Alignment *dialogPadding = manage(new Gtk::Alignment(0, 0, 1, 1));
92 dialogPadding->set_padding(12, 12, 12, 12);
93 get_vbox()->pack_start(*dialogPadding, false, false, 0);
95 Gtk::VBox *dialogBox = manage(new Gtk::VBox(false, 12));
96 dialogPadding->add(*dialogBox);
98 Gtk::Button *choose_button(manage(new class Gtk::Button(Gtk::StockID(_("Choose...")))));
99 choose_button->show();
100 choose_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_choose_pressed));
102 Gtk::Frame *target_frame=manage(new Gtk::Frame(_("Target")));
103 target_frame->set_shadow_type(Gtk::SHADOW_NONE);
104 ((Gtk::Label *) target_frame->get_label_widget())->set_markup(_("<b>Target</b>"));
105 dialogBox->pack_start(*target_frame);
106 Gtk::Alignment *targetPadding = manage(new Gtk::Alignment(0, 0, 1, 1));
107 targetPadding->set_padding(6, 0, 24, 0);
108 target_frame->add(*targetPadding);
110 Gtk::Table *target_table = manage(new Gtk::Table(2, 3, false));
111 target_table->set_row_spacings(6);
112 target_table->set_col_spacings(12);
113 targetPadding->add(*target_table);
115 Gtk::Label *filenameLabel = manage(new Gtk::Label(_("_Filename"), true));
116 filenameLabel->set_alignment(0, 0.5);
117 filenameLabel->set_mnemonic_widget(entry_filename);
118 target_table->attach(*filenameLabel, 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
119 target_table->attach(entry_filename, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
120 target_table->attach(*choose_button, 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
122 Gtk::Label *targetLabel = manage(new Gtk::Label(_("_Target"), true));
123 targetLabel->set_alignment(0, 0.5);
124 targetLabel->set_mnemonic_widget(optionmenu_target);
125 target_table->attach(*targetLabel, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
126 target_table->attach(optionmenu_target, 1, 3, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
128 toggle_single_frame.signal_toggled().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_single_frame_toggle));
130 Gtk::Frame *settings_frame=manage(new Gtk::Frame(_("Settings")));
131 settings_frame->set_shadow_type(Gtk::SHADOW_NONE);
132 ((Gtk::Label *) settings_frame->get_label_widget())->set_markup(_("<b>Settings</b>"));
133 dialogBox->pack_start(*settings_frame);
135 Gtk::Alignment *settingsPadding = manage(new Gtk::Alignment(0, 0, 1, 1));
136 settingsPadding->set_padding(6, 0, 24, 0);
137 settings_frame->add(*settingsPadding);
139 Gtk::Table *settings_table=manage(new Gtk::Table(2,2,false));
140 settings_table->set_row_spacings(6);
141 settings_table->set_col_spacings(12);
142 settingsPadding->add(*settings_table);
144 Gtk::Label *qualityLabel = manage(new Gtk::Label(_("_Quality"), true));
145 qualityLabel->set_alignment(0, 0.5);
146 qualityLabel->set_mnemonic_widget(entry_quality);
147 settings_table->attach(*qualityLabel, 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
148 settings_table->attach(entry_quality, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
150 Gtk::Label *antiAliasLabel = manage(new Gtk::Label(_("_Anti-Aliasing"), true));
151 antiAliasLabel->set_alignment(0, 0.5);
152 antiAliasLabel->set_mnemonic_widget(entry_antialias);
153 settings_table->attach(*antiAliasLabel, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
154 settings_table->attach(entry_antialias, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
156 toggle_single_frame.set_alignment(0, 0.5);
157 settings_table->attach(toggle_single_frame, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
159 dialogBox->pack_start(widget_rend_desc);
162 Gtk::Button *render_button(manage(new class Gtk::Button(Gtk::StockID("Render"))));
163 render_button->show();
164 add_action_widget(*render_button,1);
165 render_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_render_pressed));
167 Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))));
168 cancel_button->show();
169 add_action_widget(*cancel_button,0);
170 cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_cancel_pressed));
172 //set_default_response(1);
174 set_title(_("Render Settings")+String(" - ")+canvas_interface_->get_canvas()->get_name());
177 toggle_single_frame.set_active(true);
178 widget_rend_desc.disable_time_section();
183 entry_filename.set_text(Glib::build_filename(Glib::get_home_dir(),Glib::ustring("Desktop")+ETL_DIRECTORY_SEPERATOR+Glib::ustring("output.png")));
187 synfig::warning("Averted crash!");
188 entry_filename.set_text("output.png");
191 get_vbox()->show_all();
194 RenderSettings::~RenderSettings()
199 RenderSettings::on_rend_desc_changed()
201 widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
205 RenderSettings::set_target(synfig::String name)
211 RenderSettings::on_choose_pressed()
213 String filename=entry_filename.get_text();
214 if(App::dialog_saveas_file("Save Render As",filename))
215 entry_filename.set_text(filename);
219 RenderSettings::on_render_pressed()
221 String filename=entry_filename.get_text();
225 canvas_interface_->get_ui_interface()->error(_("You must supply a filename!"));
229 // If the target type is not yet defined,
230 // try to figure it out from the outfile.
231 if(target_name.empty())
235 String ext=String(find(filename.begin(),filename.end(),'.')+1,filename.end());
236 if(Target::ext_book().count(ext))
237 target_name=Target::ext_book()[ext];
241 catch(std::runtime_error x)
243 canvas_interface_->get_ui_interface()->error(_("Unable to determine proper target from filename."));
248 if(filename.empty() && target_name!="null")
250 canvas_interface_->get_ui_interface()->error(_("A filename is required for this target"));
254 Target::Handle target=Target::create(target_name,filename);
257 canvas_interface_->get_ui_interface()->error(_("Unable to create target for ")+filename);
263 target->set_canvas(canvas_interface_->get_canvas());
264 RendDesc rend_desc(widget_rend_desc.get_rend_desc());
265 rend_desc.set_antialias((int)adjustment_antialias.get_value());
267 // If we are to only render the current frame
268 if(toggle_single_frame.get_active())
269 rend_desc.set_time(canvas_interface_->get_time());
271 target->set_rend_desc(&rend_desc);
272 target->set_quality((int)adjustment_quality.get_value());
273 if( !target->init() ){
274 canvas_interface_->get_ui_interface()->error(_("Target initialisation failure"));
278 canvas_interface_->get_ui_interface()->task(_("Rendering ")+filename);
282 async_renderer->stop();
283 async_renderer.detach();
285 async_renderer=new AsyncRenderer(target);
286 async_renderer->signal_finished().connect( sigc::mem_fun(*this,&RenderSettings::on_finished));
287 async_renderer->start();
289 if(!target->render(canvas_interface_->get_ui_interface().get()))
291 canvas_interface_->get_ui_interface()->error(_("Render Failure"));
292 canvas_interface_->get_ui_interface()->amount_complete(0,10000);
297 canvas_interface_->get_ui_interface()->task(filename+_(" rendered successfully"));
298 canvas_interface_->get_ui_interface()->amount_complete(0,10000);
304 RenderSettings::on_finished()
306 canvas_interface_->get_ui_interface()->task(_("File rendered successfully"));
307 canvas_interface_->get_ui_interface()->amount_complete(0,10000);
311 RenderSettings::on_cancel_pressed()
317 RenderSettings::on_single_frame_toggle()
319 if(toggle_single_frame.get_active())
320 widget_rend_desc.disable_time_section();
322 widget_rend_desc.enable_time_section();