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 "motionscan.h"
27 #include "motionwindow.h"
38 MotionWindow::MotionWindow(MotionMain *plugin)
39 : PluginClientWindow(plugin,
46 this->plugin = plugin;
49 MotionWindow::~MotionWindow()
53 void MotionWindow::create_objects()
55 int x1 = 10, x = 10, y = 10;
61 add_subwindow(global = new MotionGlobal(plugin,
66 add_subwindow(rotate = new MotionRotate(plugin,
72 add_subwindow(title = new BC_Title(x1,
74 _("Translation search radius:\n(W/H Percent of image)")));
75 add_subwindow(global_range_w = new GlobalRange(plugin,
76 x1 + title->get_w() + 10,
78 &plugin->config.global_range_w));
79 add_subwindow(global_range_h = new GlobalRange(plugin,
80 x1 + title->get_w() + 10 + global_range_w->get_w(),
82 &plugin->config.global_range_h));
84 add_subwindow(title = new BC_Title(x2,
86 _("Rotation search radius:\n(Degrees)")));
87 add_subwindow(rotation_range = new RotationRange(plugin,
88 x2 + title->get_w() + 10,
92 add_subwindow(title = new BC_Title(x1,
94 _("Translation block size:\n(W/H Percent of image)")));
95 add_subwindow(global_block_w = new BlockSize(plugin,
96 x1 + title->get_w() + 10,
98 &plugin->config.global_block_w));
99 add_subwindow(global_block_h = new BlockSize(plugin,
100 x1 + title->get_w() + 10 + global_block_w->get_w(),
102 &plugin->config.global_block_h));
104 add_subwindow(title = new BC_Title(x2,
106 _("Rotation block size:\n(W/H Percent of image)")));
107 add_subwindow(rotation_block_w = new BlockSize(plugin,
108 x2 + title->get_w() + 10,
110 &plugin->config.rotation_block_w));
111 add_subwindow(rotation_block_h = new BlockSize(plugin,
112 x2 + title->get_w() + 10 + rotation_block_w->get_w(),
114 &plugin->config.rotation_block_h));
117 add_subwindow(title = new BC_Title(x1, y, _("Translation search steps:")));
118 add_subwindow(global_search_positions = new GlobalSearchPositions(plugin,
119 x1 + title->get_w() + 10,
122 global_search_positions->create_objects();
124 add_subwindow(title = new BC_Title(x2, y, _("Rotation search steps:")));
125 add_subwindow(rotation_search_positions = new RotationSearchPositions(plugin,
126 x2 + title->get_w() + 10,
129 rotation_search_positions->create_objects();
132 add_subwindow(title = new BC_Title(x, y, _("Translation direction:")));
133 add_subwindow(track_direction = new TrackDirection(plugin,
135 x + title->get_w() + 10,
137 track_direction->create_objects();
140 add_subwindow(title = new BC_Title(x, y + 10, _("Block X:")));
141 add_subwindow(block_x = new MotionBlockX(plugin,
143 x + title->get_w() + 10,
145 add_subwindow(block_x_text = new MotionBlockXText(plugin,
147 x + title->get_w() + 10 + block_x->get_w() + 10,
150 add_subwindow(title = new BC_Title(x2, y, _("Rotation center:")));
151 add_subwindow(rotation_center = new RotationCenter(plugin,
152 x2 + title->get_w() + 10,
159 add_subwindow(title = new BC_Title(x2, y + 10, _("Maximum angle offset:")));
160 add_subwindow(rotate_magnitude = new MotionRMagnitude(plugin,
161 x2 + title->get_w() + 10,
165 add_subwindow(title = new BC_Title(x2, y + 10, _("Rotation settling speed:")));
166 add_subwindow(rotate_return_speed = new MotionRReturnSpeed(plugin,
167 x2 + title->get_w() + 10,
174 add_subwindow(title = new BC_Title(x, y + 10, _("Block Y:")));
175 add_subwindow(block_y = new MotionBlockY(plugin,
177 x + title->get_w() + 10,
179 add_subwindow(block_y_text = new MotionBlockYText(plugin,
181 x + title->get_w() + 10 + block_y->get_w() + 10,
185 add_subwindow(title = new BC_Title(x, y + 10, _("Maximum absolute offset:")));
186 add_subwindow(magnitude = new MotionMagnitude(plugin,
187 x + title->get_w() + 10,
191 add_subwindow(title = new BC_Title(x, y + 10, _("Settling speed:")));
192 add_subwindow(return_speed = new MotionReturnSpeed(plugin,
193 x + title->get_w() + 10,
199 add_subwindow(vectors = new MotionDrawVectors(plugin,
206 add_subwindow(track_single = new TrackSingleFrame(plugin,
210 add_subwindow(title = new BC_Title(x + track_single->get_w() + 20,
212 _("Frame number:")));
213 add_subwindow(track_frame_number = new TrackFrameNumber(plugin,
215 x + track_single->get_w() + title->get_w() + 20,
219 add_subwindow(track_previous = new TrackPreviousFrame(plugin,
225 add_subwindow(previous_same = new PreviousFrameSameBlock(plugin,
232 add_subwindow(title = new BC_Title(x, y, _("Master layer:")));
233 add_subwindow(master_layer = new MasterLayer(plugin,
235 x + title->get_w() + 10,
237 master_layer->create_objects();
241 add_subwindow(title = new BC_Title(x, y, _("Action:")));
242 add_subwindow(action_type = new ActionType(plugin,
244 x + title->get_w() + 10,
246 action_type->create_objects();
252 add_subwindow(title = new BC_Title(x, y, _("Calculation:")));
253 add_subwindow(tracking_type = new TrackingType(plugin,
255 x + title->get_w() + 10,
257 tracking_type->create_objects();
265 void MotionWindow::update_mode()
267 global_range_w->update(plugin->config.global_range_w,
270 global_range_h->update(plugin->config.global_range_h,
273 rotation_range->update(plugin->config.rotation_range,
276 vectors->update(plugin->config.draw_vectors);
277 global->update(plugin->config.global);
278 rotate->update(plugin->config.rotate);
293 GlobalRange::GlobalRange(MotionMain *plugin,
303 this->plugin = plugin;
308 int GlobalRange::handle_event()
310 *value = (int)get_value();
311 plugin->send_configure_change();
318 RotationRange::RotationRange(MotionMain *plugin,
323 (int64_t)plugin->config.rotation_range,
324 (int64_t)MIN_ROTATION,
325 (int64_t)MAX_ROTATION)
327 this->plugin = plugin;
331 int RotationRange::handle_event()
333 plugin->config.rotation_range = (int)get_value();
334 plugin->send_configure_change();
341 RotationCenter::RotationCenter(MotionMain *plugin,
346 (int64_t)plugin->config.rotation_center,
347 (int64_t)-MAX_ROTATION,
348 (int64_t)MAX_ROTATION)
350 this->plugin = plugin;
354 int RotationCenter::handle_event()
356 plugin->config.rotation_center = (int)get_value();
357 plugin->send_configure_change();
366 BlockSize::BlockSize(MotionMain *plugin,
376 this->plugin = plugin;
381 int BlockSize::handle_event()
383 *value = (int)get_value();
384 plugin->send_configure_change();
400 GlobalSearchPositions::GlobalSearchPositions(MotionMain *plugin,
410 this->plugin = plugin;
412 void GlobalSearchPositions::create_objects()
414 add_item(new BC_MenuItem("16"));
415 add_item(new BC_MenuItem("32"));
416 add_item(new BC_MenuItem("64"));
417 add_item(new BC_MenuItem("128"));
418 add_item(new BC_MenuItem("256"));
419 add_item(new BC_MenuItem("512"));
420 add_item(new BC_MenuItem("1024"));
421 add_item(new BC_MenuItem("2048"));
422 add_item(new BC_MenuItem("4096"));
423 add_item(new BC_MenuItem("8192"));
424 add_item(new BC_MenuItem("16384"));
425 add_item(new BC_MenuItem("32768"));
426 add_item(new BC_MenuItem("65536"));
427 add_item(new BC_MenuItem("131072"));
428 char string[BCTEXTLEN];
429 sprintf(string, "%d", plugin->config.global_positions);
433 int GlobalSearchPositions::handle_event()
435 plugin->config.global_positions = atoi(get_text());
436 plugin->send_configure_change();
446 RotationSearchPositions::RotationSearchPositions(MotionMain *plugin,
456 this->plugin = plugin;
458 void RotationSearchPositions::create_objects()
460 add_item(new BC_MenuItem("4"));
461 add_item(new BC_MenuItem("8"));
462 add_item(new BC_MenuItem("16"));
463 add_item(new BC_MenuItem("32"));
464 char string[BCTEXTLEN];
465 sprintf(string, "%d", plugin->config.rotate_positions);
469 int RotationSearchPositions::handle_event()
471 plugin->config.rotate_positions = atoi(get_text());
472 plugin->send_configure_change();
483 MotionMagnitude::MotionMagnitude(MotionMain *plugin,
488 (int64_t)plugin->config.magnitude,
492 this->plugin = plugin;
495 int MotionMagnitude::handle_event()
497 plugin->config.magnitude = (int)get_value();
498 plugin->send_configure_change();
503 MotionReturnSpeed::MotionReturnSpeed(MotionMain *plugin,
508 (int64_t)plugin->config.return_speed,
512 this->plugin = plugin;
515 int MotionReturnSpeed::handle_event()
517 plugin->config.return_speed = (int)get_value();
518 plugin->send_configure_change();
524 MotionRMagnitude::MotionRMagnitude(MotionMain *plugin,
529 (int64_t)plugin->config.rotate_magnitude,
533 this->plugin = plugin;
536 int MotionRMagnitude::handle_event()
538 plugin->config.rotate_magnitude = (int)get_value();
539 plugin->send_configure_change();
545 MotionRReturnSpeed::MotionRReturnSpeed(MotionMain *plugin,
550 (int64_t)plugin->config.rotate_return_speed,
554 this->plugin = plugin;
557 int MotionRReturnSpeed::handle_event()
559 plugin->config.rotate_return_speed = (int)get_value();
560 plugin->send_configure_change();
568 MotionGlobal::MotionGlobal(MotionMain *plugin,
574 plugin->config.global,
575 _("Track translation"))
577 this->plugin = plugin;
581 int MotionGlobal::handle_event()
583 plugin->config.global = get_value();
584 plugin->send_configure_change();
588 MotionRotate::MotionRotate(MotionMain *plugin,
594 plugin->config.rotate,
597 this->plugin = plugin;
601 int MotionRotate::handle_event()
603 plugin->config.rotate = get_value();
604 plugin->send_configure_change();
612 MotionBlockX::MotionBlockX(MotionMain *plugin,
618 plugin->config.block_x,
622 this->plugin = plugin;
626 int MotionBlockX::handle_event()
628 plugin->config.block_x = get_value();
629 gui->block_x_text->update((float)plugin->config.block_x);
630 plugin->send_configure_change();
637 MotionBlockY::MotionBlockY(MotionMain *plugin,
643 (float)plugin->config.block_y,
647 this->plugin = plugin;
651 int MotionBlockY::handle_event()
653 plugin->config.block_y = get_value();
654 gui->block_y_text->update((float)plugin->config.block_y);
655 plugin->send_configure_change();
659 MotionBlockXText::MotionBlockXText(MotionMain *plugin,
667 (float)plugin->config.block_x)
669 this->plugin = plugin;
674 int MotionBlockXText::handle_event()
676 plugin->config.block_x = atof(get_text());
677 gui->block_x->update(plugin->config.block_x);
678 plugin->send_configure_change();
685 MotionBlockYText::MotionBlockYText(MotionMain *plugin,
693 (float)plugin->config.block_y)
695 this->plugin = plugin;
700 int MotionBlockYText::handle_event()
702 plugin->config.block_y = atof(get_text());
703 gui->block_y->update(plugin->config.block_y);
704 plugin->send_configure_change();
723 MotionDrawVectors::MotionDrawVectors(MotionMain *plugin,
729 plugin->config.draw_vectors,
733 this->plugin = plugin;
736 int MotionDrawVectors::handle_event()
738 plugin->config.draw_vectors = get_value();
739 plugin->send_configure_change();
750 TrackSingleFrame::TrackSingleFrame(MotionMain *plugin,
756 plugin->config.tracking_object == MotionScan::TRACK_SINGLE,
757 _("Track single frame"))
759 this->plugin = plugin;
763 int TrackSingleFrame::handle_event()
765 plugin->config.tracking_object = MotionScan::TRACK_SINGLE;
766 gui->track_previous->update(0);
767 gui->previous_same->update(0);
768 gui->track_frame_number->enable();
769 plugin->send_configure_change();
780 TrackFrameNumber::TrackFrameNumber(MotionMain *plugin,
784 : BC_TextBox(x, y, 100, 1, plugin->config.track_frame)
786 this->plugin = plugin;
788 if(plugin->config.tracking_object != MotionScan::TRACK_SINGLE) disable();
791 int TrackFrameNumber::handle_event()
793 plugin->config.track_frame = atol(get_text());
794 plugin->send_configure_change();
804 TrackPreviousFrame::TrackPreviousFrame(MotionMain *plugin,
810 plugin->config.tracking_object == MotionScan::TRACK_PREVIOUS,
811 _("Track previous frame"))
813 this->plugin = plugin;
816 int TrackPreviousFrame::handle_event()
818 plugin->config.tracking_object = MotionScan::TRACK_PREVIOUS;
819 gui->track_single->update(0);
820 gui->previous_same->update(0);
821 gui->track_frame_number->disable();
822 plugin->send_configure_change();
833 PreviousFrameSameBlock::PreviousFrameSameBlock(MotionMain *plugin,
839 plugin->config.tracking_object == MotionScan::PREVIOUS_SAME_BLOCK,
840 _("Previous frame same block"))
842 this->plugin = plugin;
845 int PreviousFrameSameBlock::handle_event()
847 plugin->config.tracking_object = MotionScan::PREVIOUS_SAME_BLOCK;
848 gui->track_single->update(0);
849 gui->track_previous->update(0);
850 gui->track_frame_number->disable();
851 plugin->send_configure_change();
862 MasterLayer::MasterLayer(MotionMain *plugin, MotionWindow *gui, int x, int y)
866 to_text(plugin->config.bottom_is_master))
868 this->plugin = plugin;
872 int MasterLayer::handle_event()
874 plugin->config.bottom_is_master = from_text(get_text());
875 plugin->send_configure_change();
879 void MasterLayer::create_objects()
881 add_item(new BC_MenuItem(to_text(0)));
882 add_item(new BC_MenuItem(to_text(1)));
885 int MasterLayer::from_text(char *text)
887 if(!strcmp(text, _("Top"))) return 0;
891 char* MasterLayer::to_text(int mode)
893 return mode ? _("Bottom") : _("Top");
896 int MasterLayer::calculate_w(MotionWindow *gui)
899 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0)));
900 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1)));
911 ActionType::ActionType(MotionMain *plugin, MotionWindow *gui, int x, int y)
915 to_text(plugin->config.action_type))
917 this->plugin = plugin;
921 int ActionType::handle_event()
923 plugin->config.action_type = from_text(get_text());
924 plugin->send_configure_change();
928 void ActionType::create_objects()
930 add_item(new BC_MenuItem(to_text(MotionScan::TRACK)));
931 add_item(new BC_MenuItem(to_text(MotionScan::TRACK_PIXEL)));
932 add_item(new BC_MenuItem(to_text(MotionScan::STABILIZE)));
933 add_item(new BC_MenuItem(to_text(MotionScan::STABILIZE_PIXEL)));
934 add_item(new BC_MenuItem(to_text(MotionScan::NOTHING)));
937 int ActionType::from_text(char *text)
939 if(!strcmp(text, _("Track Subpixel"))) return MotionScan::TRACK;
940 if(!strcmp(text, _("Track Pixel"))) return MotionScan::TRACK_PIXEL;
941 if(!strcmp(text, _("Stabilize Subpixel"))) return MotionScan::STABILIZE;
942 if(!strcmp(text, _("Stabilize Pixel"))) return MotionScan::STABILIZE_PIXEL;
943 if(!strcmp(text, _("Do Nothing"))) return MotionScan::NOTHING;
946 char* ActionType::to_text(int mode)
950 case MotionScan::TRACK:
951 return _("Track Subpixel");
953 case MotionScan::TRACK_PIXEL:
954 return _("Track Pixel");
956 case MotionScan::STABILIZE:
957 return _("Stabilize Subpixel");
959 case MotionScan::STABILIZE_PIXEL:
960 return _("Stabilize Pixel");
962 case MotionScan::NOTHING:
963 return _("Do Nothing");
968 int ActionType::calculate_w(MotionWindow *gui)
971 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::TRACK)));
972 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::TRACK_PIXEL)));
973 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::STABILIZE)));
974 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::STABILIZE_PIXEL)));
975 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::NOTHING)));
983 TrackingType::TrackingType(MotionMain *plugin, MotionWindow *gui, int x, int y)
987 to_text(plugin->config.tracking_type))
989 this->plugin = plugin;
993 int TrackingType::handle_event()
995 plugin->config.tracking_type = from_text(get_text());
996 plugin->send_configure_change();
1000 void TrackingType::create_objects()
1002 add_item(new BC_MenuItem(to_text(MotionScan::NO_CALCULATE)));
1003 add_item(new BC_MenuItem(to_text(MotionScan::CALCULATE)));
1004 add_item(new BC_MenuItem(to_text(MotionScan::SAVE)));
1005 add_item(new BC_MenuItem(to_text(MotionScan::LOAD)));
1008 int TrackingType::from_text(char *text)
1010 if(!strcmp(text, _("Don't Calculate"))) return MotionScan::NO_CALCULATE;
1011 if(!strcmp(text, _("Recalculate"))) return MotionScan::CALCULATE;
1012 if(!strcmp(text, _("Save coords to /tmp"))) return MotionScan::SAVE;
1013 if(!strcmp(text, _("Load coords from /tmp"))) return MotionScan::LOAD;
1016 char* TrackingType::to_text(int mode)
1020 case MotionScan::NO_CALCULATE:
1021 return _("Don't Calculate");
1023 case MotionScan::CALCULATE:
1024 return _("Recalculate");
1026 case MotionScan::SAVE:
1027 return _("Save coords to /tmp");
1029 case MotionScan::LOAD:
1030 return _("Load coords from /tmp");
1035 int TrackingType::calculate_w(MotionWindow *gui)
1038 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::NO_CALCULATE)));
1039 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::CALCULATE)));
1040 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::SAVE)));
1041 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::LOAD)));
1054 TrackDirection::TrackDirection(MotionMain *plugin, MotionWindow *gui, int x, int y)
1058 to_text(plugin->config.horizontal_only, plugin->config.vertical_only))
1060 this->plugin = plugin;
1064 int TrackDirection::handle_event()
1066 from_text(&plugin->config.horizontal_only, &plugin->config.vertical_only, get_text());
1067 plugin->send_configure_change();
1071 void TrackDirection::create_objects()
1073 add_item(new BC_MenuItem(to_text(1, 0)));
1074 add_item(new BC_MenuItem(to_text(0, 1)));
1075 add_item(new BC_MenuItem(to_text(0, 0)));
1078 void TrackDirection::from_text(int *horizontal_only, int *vertical_only, char *text)
1080 *horizontal_only = 0;
1082 if(!strcmp(text, to_text(1, 0))) *horizontal_only = 1;
1083 if(!strcmp(text, to_text(0, 1))) *vertical_only = 1;
1086 char* TrackDirection::to_text(int horizontal_only, int vertical_only)
1088 if(horizontal_only) return _("Horizontal only");
1089 if(vertical_only) return _("Vertical only");
1093 int TrackDirection::calculate_w(MotionWindow *gui)
1096 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1, 0)));
1097 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 1)));
1098 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 0)));