4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcdisplayinfo.h"
26 #include "edlsession.h"
28 #include "motion-cv.h"
29 #include "motionwindow-cv.h"
31 #include "pluginserver.h"
33 MotionCVWindow::MotionCVWindow(MotionCVMain *plugin)
34 : PluginClientWindow(plugin, 815, 600, 815, 600, 0)
36 this->plugin = plugin;
39 MotionCVWindow::~MotionCVWindow()
43 void MotionCVWindow::create_objects()
45 int x1 = 10, x = 10, y = 10;
49 add_subwindow(global = new MotionCVGlobal(plugin, this, x1, y));
50 add_subwindow(rotate = new MotionCVRotate(plugin, this, x2, y));
53 add_subwindow(title = new BC_Title(x1, y,
54 _("Translation search radius:\n(W/H Percent of image)")));
55 add_subwindow(global_range_w = new GlobalRange(plugin,
56 x1 + title->get_w() + 10, y,
57 &plugin->config.global_range_w));
58 add_subwindow(global_range_h = new GlobalRange(plugin,
59 x1 + title->get_w() + 30 + global_range_w->get_w(), y,
60 &plugin->config.global_range_h));
62 add_subwindow(title = new BC_Title(x2, y,
63 _("Rotation search radius:\n(Degrees)")));
64 add_subwindow(rotation_range =
65 new RotationRange(plugin, x2 + title->get_w() + 10, y));
68 add_subwindow(title = new BC_Title(x1, y,
69 _("Translation block size:\n(W/H Percent of image)")));
70 add_subwindow(global_block_w = new BlockSize(plugin,
71 x1 + title->get_w() + 10, y,
72 &plugin->config.global_block_w));
73 add_subwindow(global_block_h = new BlockSize(plugin,
74 x1 + title->get_w() + 30 + global_block_w->get_w(), y,
75 &plugin->config.global_block_h));
77 add_subwindow(title = new BC_Title(x2, y,
78 _("Rotation block size:\n(W/H Percent of image)")));
79 add_subwindow(rotation_block_w = new BlockSize(plugin,
80 x2 + title->get_w() + 10, y,
81 &plugin->config.rotation_block_w));
82 add_subwindow(rotation_block_h = new BlockSize(plugin,
83 x2 + title->get_w() + 30 + rotation_block_w->get_w(), y,
84 &plugin->config.rotation_block_h));
87 add_subwindow(title = new BC_Title(x1, y, _("Translation search steps:")));
88 add_subwindow(global_search_positions = new GlobalSearchPositions(plugin,
89 x1 + title->get_w() + 10, y, 80));
90 global_search_positions->create_objects();
92 add_subwindow(title = new BC_Title(x2, y, _("Rotation search steps:")));
93 add_subwindow(rotation_search_positions = new RotationSearchPositions(plugin,
94 x2 + title->get_w() + 10, y, 80));
95 rotation_search_positions->create_objects();
98 add_subwindow(title = new BC_Title(x, y, _("Translation direction:")));
99 add_subwindow(mode3 = new Mode3(plugin,
100 this, x + title->get_w() + 10, y));
101 mode3->create_objects();
104 add_subwindow(title = new BC_Title(x2, y, _("Tracking file:")));
105 add_subwindow(tracking_file = new MotionCVTrackingFile(plugin,
106 plugin->config. tracking_file, this,
107 x2 + title->get_w() + 20, y));
108 y1 += tracking_file->get_h() + 10;
110 add_subwindow(title = new BC_Title(x, y + 10, _("Block X:")));
111 add_subwindow(block_x = new MotionCVBlockX(plugin, this,
112 x + title->get_w() + 10, y));
113 add_subwindow(block_x_text = new MotionCVBlockXText(plugin,
114 this, x + title->get_w() + 10 + block_x->get_w() + 10, y + 10));
117 add_subwindow(title = new BC_Title(x, y + 10, _("Block Y:")));
118 add_subwindow(block_y = new MotionCVBlockY(plugin, this,
119 x + title->get_w() + 10, y));
120 add_subwindow(block_y_text = new MotionCVBlockYText(plugin, this,
121 x + title->get_w() + 10 + block_y->get_w() + 10, y + 10));
123 add_subwindow(title = new BC_Title(x2, y1 + 10, _("Maximum absolute offset:")));
124 add_subwindow(magnitude = new MotionCVMagnitude(plugin,
125 x2 + title->get_w() + 10, y1));
128 add_subwindow(title = new BC_Title(x2, y1 + 10, _("Settling speed:")));
129 add_subwindow(return_speed = new MotionCVReturnSpeed(plugin,
130 x2 + title->get_w() + 10, y1));
133 add_subwindow(vectors = new MotionCVDrawVectors(plugin, this, x2, y1));
134 y = y1 + vectors->get_h() + 10;
137 add_subwindow(track_single =
138 new TrackSingleFrame(plugin, this, x1, y1));
140 add_subwindow(track_previous = new TrackPreviousFrame(plugin, this, x, y));
142 add_subwindow(previous_same = new PreviousFrameSameBlock(plugin, this, x, y));
145 add_subwindow(title = new BC_Title(x, y, _("Master layer:")));
146 add_subwindow(master_layer = new MasterLayer(plugin, this,
147 x + title->get_w() + 10, y));
148 master_layer->create_objects();
149 add_subwindow(title =
150 new BC_Title(x1=x2, y1=y, _("Frame number:")));
151 add_subwindow(track_frame_number =
152 new TrackFrameNumber(plugin, this, x1 += title->get_w(), y1));
153 if( plugin->config.mode3 != MotionCVConfig::TRACK_SINGLE )
154 track_frame_number->disable();
156 add_subwindow(addtrackedframeoffset =
157 new AddTrackedFrameOffset(plugin, this, x1=x2, y1+=track_frame_number->get_h()));
158 int pef = client->server->mwindow->edl->session->video_every_frame;
159 add_subwindow(pef_title = new BC_Title(x1=x2+50, y1+=addtrackedframeoffset->get_h() + 5,
160 !pef ? _("For best results\n"
161 " Set: Play every frame\n"
162 " Preferences-> Playback-> Video Out") :
163 _("Currently using: Play every frame"), MEDIUMFONT,
164 !pef ? RED : GREEN));
167 add_subwindow(title = new BC_Title(x, y, _("Action:")));
168 add_subwindow(mode1 = new Mode1(plugin, this,
169 x + title->get_w() + 10, y));
170 mode1->create_objects();
173 add_subwindow(title = new BC_Title(x, y, _("Calculation:")));
174 add_subwindow(mode2 = new Mode2(plugin, this,
175 x + title->get_w() + 10, y));
176 mode2->create_objects();
181 void MotionCVWindow::update_mode()
183 global_range_w->update(plugin->config.global_range_w, MIN_RADIUS, MAX_RADIUS);
184 global_range_h->update(plugin->config.global_range_h, MIN_RADIUS, MAX_RADIUS);
185 rotation_range->update(plugin->config.rotation_range, MIN_ROTATION, MAX_ROTATION);
186 vectors->update(plugin->config.draw_vectors);
187 tracking_file->update(plugin->config.tracking_file);
188 global->update(plugin->config.global);
189 rotate->update(plugin->config.rotate);
190 addtrackedframeoffset->update(plugin->config.addtrackedframeoffset);
193 GlobalRange::GlobalRange(MotionCVMain *plugin, int x, int y, int *value)
194 :BC_IPot(x, y, (int64_t) * value, (int64_t) MIN_RADIUS, (int64_t) MAX_RADIUS)
196 this->plugin = plugin;
200 int GlobalRange::handle_event()
202 *value = (int)get_value();
203 plugin->send_configure_change();
207 RotationRange::RotationRange(MotionCVMain *plugin, int x, int y)
210 y, (int64_t) plugin->config.rotation_range,
211 (int64_t) MIN_ROTATION, (int64_t) MAX_ROTATION)
213 this->plugin = plugin;
216 int RotationRange::handle_event()
218 plugin->config.rotation_range = (int)get_value();
219 plugin->send_configure_change();
223 BlockSize::BlockSize(MotionCVMain *plugin, int x, int y, int *value)
224 : BC_IPot(x, y, (int64_t) * value, (int64_t) MIN_BLOCK, (int64_t) MAX_BLOCK)
226 this->plugin = plugin;
230 int BlockSize::handle_event()
232 *value = (int)get_value();
233 plugin->send_configure_change();
237 GlobalSearchPositions::GlobalSearchPositions(MotionCVMain *plugin,
239 : BC_PopupMenu(x, y, w, "", 1)
241 this->plugin = plugin;
244 void GlobalSearchPositions::create_objects()
246 add_item(new BC_MenuItem("64"));
247 add_item(new BC_MenuItem("128"));
248 add_item(new BC_MenuItem("256"));
249 add_item(new BC_MenuItem("512"));
250 add_item(new BC_MenuItem("1024"));
251 add_item(new BC_MenuItem("2048"));
252 add_item(new BC_MenuItem("4096"));
253 add_item(new BC_MenuItem("8192"));
254 add_item(new BC_MenuItem("16384"));
255 add_item(new BC_MenuItem("32768"));
256 add_item(new BC_MenuItem("65536"));
257 add_item(new BC_MenuItem("131072"));
258 char string[BCTEXTLEN];
259 sprintf(string, "%d", plugin->config.global_positions);
263 int GlobalSearchPositions::handle_event()
265 plugin->config.global_positions = atoi(get_text());
266 plugin->send_configure_change();
270 RotationSearchPositions::RotationSearchPositions(MotionCVMain *plugin,
272 : BC_PopupMenu(x, y, w, "", 1)
274 this->plugin = plugin;
277 void RotationSearchPositions::create_objects()
279 add_item(new BC_MenuItem("4"));
280 add_item(new BC_MenuItem("8"));
281 add_item(new BC_MenuItem("16"));
282 add_item(new BC_MenuItem("32"));
283 char string[BCTEXTLEN];
284 sprintf(string, "%d", plugin->config.rotate_positions);
288 int RotationSearchPositions::handle_event()
290 plugin->config.rotate_positions = atoi(get_text());
291 plugin->send_configure_change();
295 MotionCVMagnitude::MotionCVMagnitude(MotionCVMain *plugin, int x, int y)
296 : BC_IPot(x, y, (int64_t) plugin->config.magnitude, (int64_t) 0, (int64_t) 100)
298 this->plugin = plugin;
301 int MotionCVMagnitude::handle_event()
303 plugin->config.magnitude = (int)get_value();
304 plugin->send_configure_change();
308 MotionCVReturnSpeed::MotionCVReturnSpeed(MotionCVMain *plugin, int x, int y)
309 : BC_IPot(x, y, (int64_t) plugin->config.return_speed, (int64_t) 0, (int64_t) 100)
311 this->plugin = plugin;
314 int MotionCVReturnSpeed::handle_event()
316 plugin->config.return_speed = (int)get_value();
317 plugin->send_configure_change();
321 AddTrackedFrameOffset::AddTrackedFrameOffset(MotionCVMain *plugin,
322 MotionCVWindow *gui, int x, int y)
323 : BC_CheckBox(x, y, plugin->config.addtrackedframeoffset,
324 _("Add (loaded) offset from tracked frame"))
326 this->plugin = plugin;
330 int AddTrackedFrameOffset::handle_event()
332 plugin->config.addtrackedframeoffset = get_value();
333 plugin->send_configure_change();
337 MotionCVTrackingFile::MotionCVTrackingFile(MotionCVMain *plugin,
338 const char *filename, MotionCVWindow *gui, int x, int y)
339 : BC_TextBox(x, y, 250, 1, filename)
341 this->plugin = plugin;
345 int MotionCVTrackingFile::handle_event()
347 strcpy(plugin->config.tracking_file, get_text());
348 plugin->send_configure_change();
352 MotionCVGlobal::MotionCVGlobal(MotionCVMain *plugin,
353 MotionCVWindow *gui, int x, int y)
354 :BC_CheckBox(x, y, plugin->config.global, _("Track translation"))
356 this->plugin = plugin;
360 int MotionCVGlobal::handle_event()
362 plugin->config.global = get_value();
363 plugin->send_configure_change();
367 MotionCVRotate::MotionCVRotate(MotionCVMain *plugin,
368 MotionCVWindow *gui, int x, int y)
369 : BC_CheckBox(x, y, plugin->config.rotate, _("Track rotation"))
371 this->plugin = plugin;
375 int MotionCVRotate::handle_event()
377 plugin->config.rotate = get_value();
378 plugin->send_configure_change();
382 MotionCVBlockX::MotionCVBlockX(MotionCVMain *plugin,
383 MotionCVWindow *gui, int x, int y)
384 : BC_FPot(x, y, plugin->config.block_x, (float)0, (float)100)
386 this->plugin = plugin;
390 int MotionCVBlockX::handle_event()
392 plugin->config.block_x = get_value();
393 gui->block_x_text->update((float)plugin->config.block_x);
394 plugin->send_configure_change();
398 MotionCVBlockY::MotionCVBlockY(MotionCVMain *plugin,
399 MotionCVWindow *gui, int x, int y)
400 : BC_FPot(x, y, (float)plugin->config.block_y, (float)0, (float)100)
402 this->plugin = plugin;
406 int MotionCVBlockY::handle_event()
408 plugin->config.block_y = get_value();
409 gui->block_y_text->update((float)plugin->config.block_y);
410 plugin->send_configure_change();
414 MotionCVBlockXText::MotionCVBlockXText(MotionCVMain *plugin,
415 MotionCVWindow *gui, int x, int y)
416 : BC_TextBox(x, y, 75, 1, (float)plugin->config.block_x)
418 this->plugin = plugin;
423 int MotionCVBlockXText::handle_event()
425 plugin->config.block_x = atof(get_text());
426 gui->block_x->update(plugin->config.block_x);
427 plugin->send_configure_change();
431 MotionCVBlockYText::MotionCVBlockYText(MotionCVMain *plugin,
432 MotionCVWindow *gui, int x, int y)
433 : BC_TextBox(x, y, 75, 1, (float)plugin->config.block_y)
435 this->plugin = plugin;
440 int MotionCVBlockYText::handle_event()
442 plugin->config.block_y = atof(get_text());
443 gui->block_y->update(plugin->config.block_y);
444 plugin->send_configure_change();
448 MotionCVDrawVectors::MotionCVDrawVectors(MotionCVMain *plugin,
449 MotionCVWindow *gui, int x, int y)
450 : BC_CheckBox(x, y, plugin->config.draw_vectors, _("Draw vectors"))
453 this->plugin = plugin;
456 int MotionCVDrawVectors::handle_event()
458 plugin->config.draw_vectors = get_value();
459 plugin->send_configure_change();
463 TrackSingleFrame::TrackSingleFrame(MotionCVMain *plugin,
464 MotionCVWindow *gui, int x, int y)
467 y, plugin->config.mode3 == MotionCVConfig::TRACK_SINGLE,
468 _("Track single frame"))
470 this->plugin = plugin;
474 int TrackSingleFrame::handle_event()
476 plugin->config.mode3 = MotionCVConfig::TRACK_SINGLE;
477 gui->track_previous->update(0);
478 gui->previous_same->update(0);
479 gui->track_frame_number->enable();
480 plugin->send_configure_change();
484 TrackFrameNumber::TrackFrameNumber(MotionCVMain *plugin,
485 MotionCVWindow *gui, int x, int y)
486 : BC_TextBox(x, y, 100, 1, plugin->config.track_frame)
488 this->plugin = plugin;
492 int TrackFrameNumber::handle_event()
494 plugin->config.track_frame = atol(get_text());
495 plugin->send_configure_change();
499 TrackPreviousFrame::TrackPreviousFrame(MotionCVMain *plugin,
500 MotionCVWindow *gui, int x, int y)
503 y, plugin->config.mode3 == MotionCVConfig::TRACK_PREVIOUS,
504 _("Track previous frame"))
506 this->plugin = plugin;
510 int TrackPreviousFrame::handle_event()
512 plugin->config.mode3 = MotionCVConfig::TRACK_PREVIOUS;
513 gui->track_single->update(0);
514 gui->previous_same->update(0);
515 gui->track_frame_number->disable();
516 plugin->send_configure_change();
520 PreviousFrameSameBlock::PreviousFrameSameBlock(MotionCVMain *plugin,
521 MotionCVWindow *gui, int x, int y)
524 y, plugin->config.mode3 == MotionCVConfig::PREVIOUS_SAME_BLOCK,
525 _("Previous frame same block"))
527 this->plugin = plugin;
531 int PreviousFrameSameBlock::handle_event()
533 plugin->config.mode3 = MotionCVConfig::PREVIOUS_SAME_BLOCK;
534 gui->track_single->update(0);
535 gui->track_previous->update(0);
536 gui->track_frame_number->disable();
537 plugin->send_configure_change();
541 MasterLayer::MasterLayer(MotionCVMain *plugin, MotionCVWindow *gui, int x,
543 : BC_PopupMenu(x, y, calculate_w(gui),
544 to_text(plugin->config.bottom_is_master))
546 this->plugin = plugin;
550 int MasterLayer::handle_event()
552 plugin->config.bottom_is_master = from_text(get_text());
553 plugin->send_configure_change();
557 void MasterLayer::create_objects()
559 add_item(new BC_MenuItem(to_text(0)));
560 add_item(new BC_MenuItem(to_text(1)));
563 int MasterLayer::from_text(char *text)
565 if( !strcmp(text, _("Top")) ) return 0;
569 const char *MasterLayer::to_text(int mode)
571 return mode ? _("Bottom") : _("Top");
574 int MasterLayer::calculate_w(MotionCVWindow *gui)
577 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0)));
578 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1)));
582 Mode1::Mode1(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
583 : BC_PopupMenu(x, y, calculate_w(gui), to_text(plugin->config.mode1))
585 this->plugin = plugin;
589 int Mode1::handle_event()
591 plugin->config.mode1 = from_text(get_text());
592 plugin->send_configure_change();
596 void Mode1::create_objects()
598 add_item(new BC_MenuItem(to_text(MotionCVConfig::TRACK)));
599 add_item(new BC_MenuItem(to_text(MotionCVConfig::TRACK_PIXEL)));
600 add_item(new BC_MenuItem(to_text(MotionCVConfig::STABILIZE)));
601 add_item(new BC_MenuItem(to_text(MotionCVConfig::STABILIZE_PIXEL)));
602 add_item(new BC_MenuItem(to_text(MotionCVConfig::NOTHING)));
605 int Mode1::from_text(char *text)
607 if( !strcmp(text, _("Track Subpixel")) ) return MotionCVConfig::TRACK;
608 if( !strcmp(text, _("Track Pixel")) ) return MotionCVConfig::TRACK_PIXEL;
609 if( !strcmp(text, _("Stabilize Subpixel")) ) return MotionCVConfig::STABILIZE;
610 if( !strcmp(text, _("Stabilize Pixel")) ) return MotionCVConfig::STABILIZE_PIXEL;
611 //if( !strcmp(text, _("Do Nothing")) ) return MotionCVConfig::NOTHING;
612 return MotionCVConfig::NOTHING;
615 const char *Mode1::to_text(int mode)
618 case MotionCVConfig::TRACK: return _("Track Subpixel");
619 case MotionCVConfig::TRACK_PIXEL: return _("Track Pixel");
620 case MotionCVConfig::STABILIZE: return _("Stabilize Subpixel");
621 case MotionCVConfig::STABILIZE_PIXEL: return _("Stabilize Pixel");
622 case MotionCVConfig::NOTHING: return _("Do Nothing");
627 int Mode1::calculate_w(MotionCVWindow *gui)
630 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::TRACK)));
631 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::TRACK_PIXEL)));
632 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::STABILIZE)));
633 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::STABILIZE_PIXEL)));
634 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::NOTHING)));
638 Mode2::Mode2(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
639 : BC_PopupMenu(x, y, calculate_w(gui), to_text(plugin->config.mode2))
641 this->plugin = plugin;
645 int Mode2::handle_event()
647 plugin->config.mode2 = from_text(get_text());
648 plugin->send_configure_change();
652 void Mode2::create_objects()
654 add_item(new BC_MenuItem(to_text(MotionCVConfig::SAVE)));
655 add_item(new BC_MenuItem(to_text(MotionCVConfig::LOAD)));
656 add_item(new BC_MenuItem(to_text(MotionCVConfig::RECALCULATE)));
657 add_item(new BC_MenuItem(to_text(MotionCVConfig::NO_CALCULATE)));
660 int Mode2::from_text(char *text)
662 if( !strcmp(text, _("Recalculate")) ) return MotionCVConfig::RECALCULATE;
663 if( !strcmp(text, _("Save coords to tracking file")) ) return MotionCVConfig::SAVE;
664 if( !strcmp(text, _("Load coords from tracking file")) ) return MotionCVConfig::LOAD;
665 //if( !strcmp(text, _("Don't Calculate")) ) return MotionCVConfig::NO_CALCULATE;
666 return MotionCVConfig::NO_CALCULATE;
669 const char *Mode2::to_text(int mode)
672 case MotionCVConfig::NO_CALCULATE: return _("Don't Calculate");
673 case MotionCVConfig::RECALCULATE: return _("Recalculate");
674 case MotionCVConfig::SAVE: return _("Save coords to tracking file");
675 case MotionCVConfig::LOAD: return _("Load coords from tracking file");
680 int Mode2::calculate_w(MotionCVWindow *gui)
683 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::NO_CALCULATE)));
684 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::RECALCULATE)));
685 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::SAVE)));
686 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::LOAD)));
690 Mode3::Mode3(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
692 BC_PopupMenu(x, y, calculate_w(gui),
693 to_text(plugin->config.horizontal_only, plugin->config.vertical_only))
695 this->plugin = plugin;
699 int Mode3::handle_event()
701 from_text(&plugin->config.horizontal_only,
702 &plugin->config.vertical_only, get_text());
703 plugin->send_configure_change();
707 void Mode3::create_objects()
709 add_item(new BC_MenuItem(to_text(1, 0)));
710 add_item(new BC_MenuItem(to_text(0, 1)));
711 add_item(new BC_MenuItem(to_text(0, 0)));
714 void Mode3::from_text(int *horizontal_only, int *vertical_only, char *text)
716 *horizontal_only = 0;
718 if( !strcmp(text, to_text(1, 0)) ) *horizontal_only = 1;
719 if( !strcmp(text, to_text(0, 1)) ) *vertical_only = 1;
722 const char *Mode3::to_text(int horizontal_only, int vertical_only)
724 if( horizontal_only ) return _("Horizontal only");
725 if( vertical_only ) return _("Vertical only");
729 int Mode3::calculate_w(MotionCVWindow *gui)
732 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1, 0)));
733 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 1)));
734 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 0)));