1 #include "bcdisplayinfo.h"
7 #include "pluginvclient.h"
8 #include "rotateframe.h"
15 #define _(String) gettext(String)
16 #define gettext_noop(String) String
17 #define N_(String) gettext_noop (String)
20 #define SQR(x) ((x) * (x))
33 int equivalent(RotateConfig &that);
34 void copy_from(RotateConfig &that);
35 void interpolate(RotateConfig &prev,
45 class RotateToggle : public BC_Radial
48 RotateToggle(RotateWindow *window,
62 class RotateInterpolate : public BC_CheckBox
65 RotateInterpolate(RotateEffect *plugin, int x, int y);
70 class RotateFine : public BC_FPot
73 RotateFine(RotateWindow *window,
83 class RotateWindow : public BC_Window
86 RotateWindow(RotateEffect *plugin, int x, int y);
95 RotateToggle *toggle0;
96 RotateToggle *toggle90;
97 RotateToggle *toggle180;
98 RotateToggle *toggle270;
100 RotateInterpolate *bilinear;
104 PLUGIN_THREAD_HEADER(RotateEffect, RotateThread, RotateWindow)
107 class RotateEffect : public PluginVClient
110 RotateEffect(PluginServer *server);
113 int process_realtime(VFrame *input, VFrame *output);
115 char* plugin_title();
121 int load_configuration();
124 void save_data(KeyFrame *keyframe);
125 void read_data(KeyFrame *keyframe);
129 RotateThread *thread;
132 int need_reconfigure;
141 REGISTER_PLUGIN(RotateEffect)
160 RotateConfig::RotateConfig()
165 int RotateConfig::equivalent(RotateConfig &that)
167 return EQUIV(angle, that.angle) && bilinear == that.bilinear;
170 void RotateConfig::copy_from(RotateConfig &that)
173 bilinear = that.bilinear;
176 void RotateConfig::interpolate(RotateConfig &prev,
182 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
183 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
185 this->angle = prev.angle * prev_scale + next.angle * next_scale;
186 bilinear = prev.bilinear;
199 RotateToggle::RotateToggle(RotateWindow *window,
200 RotateEffect *plugin,
206 : BC_Radial(x, y, init_value, string)
209 this->plugin = plugin;
210 this->window = window;
213 int RotateToggle::handle_event()
215 plugin->config.angle = (float)value;
217 plugin->send_configure_change();
223 RotateInterpolate::RotateInterpolate(RotateEffect *plugin, int x, int y)
224 : BC_CheckBox(x, y, plugin->config.bilinear, _("Interpolate"))
226 this->plugin = plugin;
228 int RotateInterpolate::handle_event()
230 plugin->config.bilinear = get_value();
231 plugin->send_configure_change();
238 RotateFine::RotateFine(RotateWindow *window, RotateEffect *plugin, int x, int y)
241 (float)plugin->config.angle,
245 this->window = window;
246 this->plugin = plugin;
250 int RotateFine::handle_event()
252 plugin->config.angle = get_value();
253 window->update_toggles();
254 plugin->send_configure_change();
267 RotateWindow::RotateWindow(RotateEffect *plugin, int x, int y)
268 : BC_Window(plugin->gui_string,
279 this->plugin = plugin;
284 int RotateWindow::create_objects()
291 add_tool(new BC_Title(x, y, _("Rotate")));
294 add_tool(toggle0 = new RotateToggle(this,
296 plugin->config.angle == 0,
303 add_tool(toggle90 = new RotateToggle(this,
305 plugin->config.angle == 90,
312 add_tool(toggle180 = new RotateToggle(this,
314 plugin->config.angle == 180,
321 add_tool(toggle270 = new RotateToggle(this,
323 plugin->config.angle == 270,
328 add_subwindow(bilinear = new RotateInterpolate(plugin, 10, y + 60));
331 add_tool(fine = new RotateFine(this, plugin, x, y));
332 y += fine->get_h() + 10;
333 add_tool(new BC_Title(x, y, _("Angle")));
345 int RotateWindow::close_event()
347 // Set result to 1 to indicate a client side close
352 int RotateWindow::update()
356 bilinear->update(plugin->config.bilinear);
360 int RotateWindow::update_fine()
362 fine->update(plugin->config.angle);
366 int RotateWindow::update_toggles()
368 toggle0->update(EQUIV(plugin->config.angle, 0));
369 toggle90->update(EQUIV(plugin->config.angle, 90));
370 toggle180->update(EQUIV(plugin->config.angle, 180));
371 toggle270->update(EQUIV(plugin->config.angle, 270));
389 PLUGIN_THREAD_OBJECT(RotateEffect, RotateThread, RotateWindow)
408 RotateEffect::RotateEffect(PluginServer *server)
409 : PluginVClient(server)
413 need_reconfigure = 1;
414 PLUGIN_CONSTRUCTOR_MACRO
417 RotateEffect::~RotateEffect()
419 PLUGIN_DESTRUCTOR_MACRO
420 if(engine) delete engine;
421 if(temp_frame) delete temp_frame;
426 char* RotateEffect::plugin_title()
431 int RotateEffect::is_realtime()
436 NEW_PICON_MACRO(RotateEffect)
438 SET_STRING_MACRO(RotateEffect)
440 SHOW_GUI_MACRO(RotateEffect, RotateThread)
442 RAISE_WINDOW_MACRO(RotateEffect)
445 void RotateEffect::update_gui()
449 load_configuration();
450 thread->window->lock_window();
451 thread->window->update();
452 thread->window->unlock_window();
456 LOAD_CONFIGURATION_MACRO(RotateEffect, RotateConfig)
460 int RotateEffect::load_defaults()
462 char directory[1024], string[1024];
463 // set the default directory
464 sprintf(directory, "%srotate.rc", BCASTDIR);
467 defaults = new Defaults(directory);
470 config.angle = defaults->get("ANGLE", (float)config.angle);
471 config.bilinear = defaults->get("INTERPOLATE", (int)config.bilinear);
475 int RotateEffect::save_defaults()
477 defaults->update("ANGLE", (float)config.angle);
478 defaults->update("INTERPOLATE", (int)config.bilinear);
483 void RotateEffect::save_data(KeyFrame *keyframe)
487 // cause data to be stored directly in text
488 output.set_shared_string(keyframe->data, MESSAGESIZE);
489 output.tag.set_title("ROTATE");
490 output.tag.set_property("ANGLE", (float)config.angle);
491 output.tag.set_property("INTERPOLATE", (int)config.bilinear);
493 output.terminate_string();
494 // data is now in *text
497 void RotateEffect::read_data(KeyFrame *keyframe)
501 input.set_shared_string(keyframe->data, strlen(keyframe->data));
507 result = input.read_tag();
511 if(input.tag.title_is("ROTATE"))
513 config.angle = input.tag.get_property("ANGLE", (float)config.angle);
514 config.bilinear = input.tag.get_property("INTERPOLATE", (int)config.bilinear);
520 int RotateEffect::process_realtime(VFrame *input, VFrame *output)
522 load_configuration();
525 //printf("RotateEffect::process_realtime 1 %d %f\n", config.bilinear, config.angle);
528 temp_frame = new VFrame(0,
531 input->get_color_model());
533 if(!engine) engine = new RotateFrame(PluginClient::smp + 1,
537 temp_frame->copy_from(input);
539 engine->rotate(output,