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"
23 #include "bcsignals.h"
27 #include "motionscan-hv.h"
28 #include "motionwindow.h"
39 MotionWindow::MotionWindow(MotionMain2 *plugin)
40 : PluginClientWindow(plugin, 680, 660, 680, 660, 0)
42 this->plugin = plugin;
45 MotionWindow::~MotionWindow()
49 void MotionWindow::create_objects()
51 int x1[] = { 10, get_w()/2 };
52 int x = 10, y = 10, y1 = 10;
56 for(int i = 0; i < TOTAL_POINTS; i++)
59 char *global_title[] =
64 add_subwindow(global[i] = new MotionGlobal(plugin,
68 &plugin->config.global[i],
72 add_subwindow(title = new BC_Title(x1[i],
74 _("Translation search radius:\n(W/H Percent of image)")));
75 add_subwindow(global_range_w[i] = new MotionPot(plugin,
76 x1[i] + title->get_w() + 10,
78 &plugin->config.global_range_w[i],
81 add_subwindow(global_range_h[i] = new MotionPot(plugin,
82 x1[i] + title->get_w() + 10 + global_range_w[i]->get_w(),
84 &plugin->config.global_range_h[i],
90 add_subwindow(title = new BC_Title(x1[i],
92 _("Translation search offset:\n(X/Y Percent of image)")));
93 add_subwindow(global_origin_x[i] = new MotionPot(plugin,
94 x1[i] + title->get_w() + 10,
96 &plugin->config.global_origin_x[i],
99 add_subwindow(global_origin_y[i] = new MotionPot(plugin,
100 x1[i] + title->get_w() + 10 + global_origin_x[i]->get_w(),
102 &plugin->config.global_origin_y[i],
107 add_subwindow(title = new BC_Title(x1[i],
109 _("Translation block size:\n(W/H Percent of image)")));
110 add_subwindow(global_block_w[i] = new MotionPot(plugin,
111 x1[i] + title->get_w() + 10,
113 &plugin->config.global_block_w[i],
116 add_subwindow(global_block_h[i] = new MotionPot(plugin,
117 x1[i] + title->get_w() + 10 + global_block_w[i]->get_w(),
119 &plugin->config.global_block_h[i],
125 add_subwindow(title = new BC_Title(x1[i], y + 10, _("Block X:")));
126 add_subwindow(block_x[i] = new MotionBlockX(plugin,
128 x1[i] + title->get_w() + 10,
131 add_subwindow(block_x_text[i] = new MotionBlockXText(plugin,
133 x1[i] + title->get_w() + 10 + block_x[i]->get_w() + 10,
138 add_subwindow(title = new BC_Title(x1[i], y + 10, _("Block Y:")));
139 add_subwindow(block_y[i] = new MotionBlockY(plugin,
141 x1[i] + title->get_w() + 10,
144 add_subwindow(block_y_text[i] = new MotionBlockYText(plugin,
146 x1[i] + title->get_w() + 10 + block_y[i]->get_w() + 10,
152 add_subwindow(vectors[i] = new MotionDrawVectors(plugin,
161 add_subwindow(new BC_Bar(x, y, get_w() - x * 2));
163 add_subwindow(title = new BC_Title(x, y, _("Search steps:")));
164 add_subwindow(global_search_positions = new GlobalSearchPositions(plugin,
165 x + title->get_w() + 10,
168 global_search_positions->create_objects();
171 add_subwindow(title = new BC_Title(x, y, _("Search directions:")));
172 add_subwindow(tracking_direction = new TrackingDirection(plugin,
174 x + title->get_w() + 10,
176 tracking_direction->create_objects();
179 add_subwindow(title = new BC_Title(x, y + 10, _("Maximum absolute offset:")));
180 add_subwindow(magnitude = new MotionMagnitude(plugin,
181 x + title->get_w() + 10,
185 add_subwindow(title = new BC_Title(x, y + 10, _("Settling speed:")));
186 add_subwindow(return_speed = new MotionReturnSpeed(plugin,
187 x + title->get_w() + 10,
192 add_subwindow(track_single = new TrackSingleFrame(plugin,
196 add_subwindow(title = new BC_Title(x + track_single->get_w() + 20,
198 _("Frame number:")));
199 add_subwindow(track_frame_number = new TrackFrameNumber(plugin,
201 x + track_single->get_w() + title->get_w() + 20,
205 add_subwindow(track_previous = new TrackPreviousFrame(plugin,
211 add_subwindow(previous_same = new PreviousFrameSameBlock(plugin,
218 add_subwindow(title = new BC_Title(x, y, _("Master layer:")));
219 add_subwindow(master_layer = new MasterLayer(plugin,
221 x + title->get_w() + 10,
223 master_layer->create_objects();
227 add_subwindow(title = new BC_Title(x, y, _("Action:")));
228 add_subwindow(action = new Action(plugin,
230 x + title->get_w() + 10,
232 action->create_objects();
238 add_subwindow(title = new BC_Title(x, y, _("Calculation:")));
239 add_subwindow(calculation = new Calculation(plugin,
241 x + title->get_w() + 10,
243 calculation->create_objects();
251 void MotionWindow::update_mode()
253 for(int i = 0; i < TOTAL_POINTS; i++)
255 global_range_w[i]->update(plugin->config.global_range_w[i],
258 global_range_h[i]->update(plugin->config.global_range_h[i],
261 vectors[i]->update(plugin->config.draw_vectors[i]);
262 global[i]->update(plugin->config.global[i]);
278 MotionGlobal::MotionGlobal(MotionMain2 *plugin,
289 this->plugin = plugin;
294 int MotionGlobal::handle_event()
296 *value = get_value();
297 plugin->send_configure_change();
302 MotionPot::MotionPot(MotionMain2 *plugin,
314 this->plugin = plugin;
319 int MotionPot::handle_event()
321 *value = (int)get_value();
322 plugin->send_configure_change();
337 GlobalSearchPositions::GlobalSearchPositions(MotionMain2 *plugin,
347 this->plugin = plugin;
349 void GlobalSearchPositions::create_objects()
351 add_item(new BC_MenuItem("16"));
352 add_item(new BC_MenuItem("32"));
353 add_item(new BC_MenuItem("64"));
354 add_item(new BC_MenuItem("128"));
355 add_item(new BC_MenuItem("256"));
356 add_item(new BC_MenuItem("512"));
357 add_item(new BC_MenuItem("1024"));
358 add_item(new BC_MenuItem("2048"));
359 add_item(new BC_MenuItem("4096"));
360 add_item(new BC_MenuItem("8192"));
361 add_item(new BC_MenuItem("16384"));
362 add_item(new BC_MenuItem("32768"));
363 add_item(new BC_MenuItem("65536"));
364 add_item(new BC_MenuItem("131072"));
365 char string[BCTEXTLEN];
366 sprintf(string, "%d", plugin->config.global_positions);
370 int GlobalSearchPositions::handle_event()
372 plugin->config.global_positions = atoi(get_text());
373 plugin->send_configure_change();
388 MotionMagnitude::MotionMagnitude(MotionMain2 *plugin,
393 (int64_t)plugin->config.magnitude,
397 this->plugin = plugin;
400 int MotionMagnitude::handle_event()
402 plugin->config.magnitude = (int)get_value();
403 plugin->send_configure_change();
408 MotionReturnSpeed::MotionReturnSpeed(MotionMain2 *plugin,
413 (int64_t)plugin->config.return_speed,
417 this->plugin = plugin;
420 int MotionReturnSpeed::handle_event()
422 plugin->config.return_speed = (int)get_value();
423 plugin->send_configure_change();
431 MotionBlockX::MotionBlockX(MotionMain2 *plugin,
438 (float)plugin->config.block_x[number],
442 this->plugin = plugin;
444 this->number = number;
447 int MotionBlockX::handle_event()
449 plugin->config.block_x[number] = get_value();
450 gui->block_x_text[number]->update((float)plugin->config.block_x[number]);
451 plugin->send_configure_change();
458 MotionBlockY::MotionBlockY(MotionMain2 *plugin,
465 (float)plugin->config.block_y[number],
469 this->plugin = plugin;
471 this->number = number;
474 int MotionBlockY::handle_event()
476 plugin->config.block_y[number] = get_value();
477 gui->block_y_text[number]->update((float)plugin->config.block_y[number]);
478 plugin->send_configure_change();
482 MotionBlockXText::MotionBlockXText(MotionMain2 *plugin,
491 (float)plugin->config.block_x[number])
493 this->plugin = plugin;
495 this->number = number;
499 int MotionBlockXText::handle_event()
501 plugin->config.block_x[number] = atof(get_text());
502 gui->block_x[number]->update(plugin->config.block_x[number]);
503 plugin->send_configure_change();
510 MotionBlockYText::MotionBlockYText(MotionMain2 *plugin,
519 (float)plugin->config.block_y[number])
521 this->plugin = plugin;
523 this->number = number;
527 int MotionBlockYText::handle_event()
529 plugin->config.block_y[number] = atof(get_text());
530 gui->block_y[number]->update(plugin->config.block_y[number]);
531 plugin->send_configure_change();
550 MotionDrawVectors::MotionDrawVectors(MotionMain2 *plugin,
557 plugin->config.draw_vectors[number],
561 this->plugin = plugin;
562 this->number = number;
565 int MotionDrawVectors::handle_event()
567 plugin->config.draw_vectors[number] = get_value();
568 plugin->send_configure_change();
579 TrackSingleFrame::TrackSingleFrame(MotionMain2 *plugin,
585 plugin->config.tracking_object == MotionScan::TRACK_SINGLE,
586 _("Track single frame"))
588 this->plugin = plugin;
592 int TrackSingleFrame::handle_event()
594 plugin->config.tracking_object = MotionScan::TRACK_SINGLE;
595 gui->track_previous->update(0);
596 gui->previous_same->update(0);
597 gui->track_frame_number->enable();
598 plugin->send_configure_change();
609 TrackFrameNumber::TrackFrameNumber(MotionMain2 *plugin,
613 : BC_TextBox(x, y, 100, 1, plugin->config.track_frame)
615 this->plugin = plugin;
617 if(plugin->config.tracking_object != MotionScan::TRACK_SINGLE) disable();
620 int TrackFrameNumber::handle_event()
622 plugin->config.track_frame = atol(get_text());
623 plugin->send_configure_change();
633 TrackPreviousFrame::TrackPreviousFrame(MotionMain2 *plugin,
639 plugin->config.tracking_object == MotionScan::TRACK_PREVIOUS,
640 _("Track previous frame"))
642 this->plugin = plugin;
645 int TrackPreviousFrame::handle_event()
647 plugin->config.tracking_object = MotionScan::TRACK_PREVIOUS;
648 gui->track_single->update(0);
649 gui->previous_same->update(0);
650 gui->track_frame_number->disable();
651 plugin->send_configure_change();
662 PreviousFrameSameBlock::PreviousFrameSameBlock(MotionMain2 *plugin,
668 plugin->config.tracking_object == MotionScan::PREVIOUS_SAME_BLOCK,
669 _("Previous frame same block"))
671 this->plugin = plugin;
674 int PreviousFrameSameBlock::handle_event()
676 plugin->config.tracking_object = MotionScan::PREVIOUS_SAME_BLOCK;
677 gui->track_single->update(0);
678 gui->track_previous->update(0);
679 gui->track_frame_number->disable();
680 plugin->send_configure_change();
691 MasterLayer::MasterLayer(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
695 to_text(plugin->config.bottom_is_master))
697 this->plugin = plugin;
701 int MasterLayer::handle_event()
703 plugin->config.bottom_is_master = from_text(get_text());
704 plugin->send_configure_change();
708 void MasterLayer::create_objects()
710 add_item(new BC_MenuItem(to_text(0)));
711 add_item(new BC_MenuItem(to_text(1)));
714 int MasterLayer::from_text(char *text)
716 if(!strcmp(text, _("Top"))) return 0;
720 char* MasterLayer::to_text(int mode)
722 return mode ? _("Bottom") : _("Top");
725 int MasterLayer::calculate_w(MotionWindow *gui)
728 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0)));
729 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1)));
740 Action::Action(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
744 to_text(plugin->config.action))
746 this->plugin = plugin;
750 int Action::handle_event()
752 plugin->config.action = from_text(get_text());
753 plugin->send_configure_change();
757 void Action::create_objects()
759 add_item(new BC_MenuItem(to_text(MotionScan::TRACK)));
760 add_item(new BC_MenuItem(to_text(MotionScan::TRACK_PIXEL)));
761 add_item(new BC_MenuItem(to_text(MotionScan::STABILIZE)));
762 add_item(new BC_MenuItem(to_text(MotionScan::STABILIZE_PIXEL)));
763 add_item(new BC_MenuItem(to_text(MotionScan::NOTHING)));
766 int Action::from_text(char *text)
768 if(!strcmp(text, _("Track"))) return MotionScan::TRACK;
769 if(!strcmp(text, _("Track Pixel"))) return MotionScan::TRACK_PIXEL;
770 if(!strcmp(text, _("Stabilize"))) return MotionScan::STABILIZE;
771 if(!strcmp(text, _("Stabilize Pixel"))) return MotionScan::STABILIZE_PIXEL;
772 if(!strcmp(text, _("Do Nothing"))) return MotionScan::NOTHING;
776 char* Action::to_text(int mode)
780 case MotionScan::TRACK:
783 case MotionScan::TRACK_PIXEL:
784 return _("Track Pixel");
786 case MotionScan::STABILIZE:
787 return _("Stabilize");
789 case MotionScan::STABILIZE_PIXEL:
790 return _("Stabilize Pixel");
792 case MotionScan::NOTHING:
793 return _("Do Nothing");
801 int Action::calculate_w(MotionWindow *gui)
804 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::TRACK)));
805 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::TRACK_PIXEL)));
806 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::STABILIZE)));
807 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::STABILIZE_PIXEL)));
808 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::NOTHING)));
816 Calculation::Calculation(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
820 to_text(plugin->config.calculation))
822 this->plugin = plugin;
826 int Calculation::handle_event()
828 plugin->config.calculation = from_text(get_text());
829 plugin->send_configure_change();
833 void Calculation::create_objects()
835 add_item(new BC_MenuItem(to_text(MotionScan::NO_CALCULATE)));
836 add_item(new BC_MenuItem(to_text(MotionScan::CALCULATE)));
837 add_item(new BC_MenuItem(to_text(MotionScan::SAVE)));
838 add_item(new BC_MenuItem(to_text(MotionScan::LOAD)));
841 int Calculation::from_text(char *text)
843 if(!strcmp(text, _("Don't Calculate"))) return MotionScan::NO_CALCULATE;
844 if(!strcmp(text, _("Recalculate"))) return MotionScan::CALCULATE;
845 if(!strcmp(text, _("Save coords to /tmp"))) return MotionScan::SAVE;
846 if(!strcmp(text, _("Load coords from /tmp"))) return MotionScan::LOAD;
850 char* Calculation::to_text(int mode)
854 case MotionScan::NO_CALCULATE:
855 return _("Don't Calculate");
857 case MotionScan::CALCULATE:
858 return _("Recalculate");
860 case MotionScan::SAVE:
861 return _("Save coords to /tmp");
863 case MotionScan::LOAD:
864 return _("Load coords from /tmp");
872 int Calculation::calculate_w(MotionWindow *gui)
875 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::NO_CALCULATE)));
876 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::CALCULATE)));
877 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::SAVE)));
878 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::LOAD)));
891 TrackingDirection::TrackingDirection(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
895 to_text(plugin->config.horizontal_only, plugin->config.vertical_only))
897 this->plugin = plugin;
901 int TrackingDirection::handle_event()
903 from_text(&plugin->config.horizontal_only, &plugin->config.vertical_only, get_text());
904 plugin->send_configure_change();
908 void TrackingDirection::create_objects()
910 add_item(new BC_MenuItem(to_text(1, 0)));
911 add_item(new BC_MenuItem(to_text(0, 1)));
912 add_item(new BC_MenuItem(to_text(0, 0)));
915 void TrackingDirection::from_text(int *horizontal_only, int *vertical_only, char *text)
917 *horizontal_only = 0;
919 if(!strcmp(text, to_text(1, 0))) *horizontal_only = 1;
920 if(!strcmp(text, to_text(0, 1))) *vertical_only = 1;
923 char* TrackingDirection::to_text(int horizontal_only, int vertical_only)
925 if(horizontal_only) return _("Horizontal only");
926 if(vertical_only) return _("Vertical only");
930 int TrackingDirection::calculate_w(MotionWindow *gui)
933 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1, 0)));
934 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 1)));
935 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 0)));