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.h"
28 #include "motionwindow.h"
39 MotionWindow::MotionWindow(MotionMain2 *plugin)
40 : PluginClientWindow(plugin,
47 this->plugin = plugin;
50 MotionWindow::~MotionWindow()
54 void MotionWindow::create_objects()
56 int x1[] = { 10, 310 };
57 int x = 10, y = 10, y1 = 10;
61 for(int i = 0; i < TOTAL_POINTS; i++)
64 char *global_title[] =
69 add_subwindow(global[i] = new MotionGlobal(plugin,
73 &plugin->config.global[i],
77 add_subwindow(title = new BC_Title(x1[i],
79 _("Translation search radius:\n(W/H Percent of image)")));
80 add_subwindow(global_range_w[i] = new MotionPot(plugin,
81 x1[i] + title->get_w() + 10,
83 &plugin->config.global_range_w[i],
86 add_subwindow(global_range_h[i] = new MotionPot(plugin,
87 x1[i] + title->get_w() + 10 + global_range_w[i]->get_w(),
89 &plugin->config.global_range_h[i],
95 add_subwindow(title = new BC_Title(x1[i],
97 _("Translation search offset:\n(X/Y Percent of image)")));
98 add_subwindow(global_origin_x[i] = new MotionPot(plugin,
99 x1[i] + title->get_w() + 10,
101 &plugin->config.global_origin_x[i],
104 add_subwindow(global_origin_y[i] = new MotionPot(plugin,
105 x1[i] + title->get_w() + 10 + global_origin_x[i]->get_w(),
107 &plugin->config.global_origin_y[i],
112 add_subwindow(title = new BC_Title(x1[i],
114 _("Translation block size:\n(W/H Percent of image)")));
115 add_subwindow(global_block_w[i] = new MotionPot(plugin,
116 x1[i] + title->get_w() + 10,
118 &plugin->config.global_block_w[i],
121 add_subwindow(global_block_h[i] = new MotionPot(plugin,
122 x1[i] + title->get_w() + 10 + global_block_w[i]->get_w(),
124 &plugin->config.global_block_h[i],
130 add_subwindow(title = new BC_Title(x1[i], y + 10, _("Block X:")));
131 add_subwindow(block_x[i] = new MotionBlockX(plugin,
133 x1[i] + title->get_w() + 10,
136 add_subwindow(block_x_text[i] = new MotionBlockXText(plugin,
138 x1[i] + title->get_w() + 10 + block_x[i]->get_w() + 10,
143 add_subwindow(title = new BC_Title(x1[i], y + 10, _("Block Y:")));
144 add_subwindow(block_y[i] = new MotionBlockY(plugin,
146 x1[i] + title->get_w() + 10,
149 add_subwindow(block_y_text[i] = new MotionBlockYText(plugin,
151 x1[i] + title->get_w() + 10 + block_y[i]->get_w() + 10,
157 add_subwindow(vectors[i] = new MotionDrawVectors(plugin,
166 add_subwindow(new BC_Bar(x, y, get_w() - x * 2));
168 add_subwindow(title = new BC_Title(x, y, _("Search steps:")));
169 add_subwindow(global_search_positions = new GlobalSearchPositions(plugin,
170 x + title->get_w() + 10,
173 global_search_positions->create_objects();
176 add_subwindow(title = new BC_Title(x, y, _("Search directions:")));
177 add_subwindow(tracking_direction = new TrackingDirection(plugin,
179 x + title->get_w() + 10,
181 tracking_direction->create_objects();
184 add_subwindow(title = new BC_Title(x, y + 10, _("Maximum absolute offset:")));
185 add_subwindow(magnitude = new MotionMagnitude(plugin,
186 x + title->get_w() + 10,
190 add_subwindow(title = new BC_Title(x, y + 10, _("Settling speed:")));
191 add_subwindow(return_speed = new MotionReturnSpeed(plugin,
192 x + title->get_w() + 10,
197 add_subwindow(track_single = new TrackSingleFrame(plugin,
201 add_subwindow(title = new BC_Title(x + track_single->get_w() + 20,
203 _("Frame number:")));
204 add_subwindow(track_frame_number = new TrackFrameNumber(plugin,
206 x + track_single->get_w() + title->get_w() + 20,
210 add_subwindow(track_previous = new TrackPreviousFrame(plugin,
216 add_subwindow(previous_same = new PreviousFrameSameBlock(plugin,
223 add_subwindow(title = new BC_Title(x, y, _("Master layer:")));
224 add_subwindow(master_layer = new MasterLayer(plugin,
226 x + title->get_w() + 10,
228 master_layer->create_objects();
232 add_subwindow(title = new BC_Title(x, y, _("Action:")));
233 add_subwindow(action = new Action(plugin,
235 x + title->get_w() + 10,
237 action->create_objects();
243 add_subwindow(title = new BC_Title(x, y, _("Calculation:")));
244 add_subwindow(calculation = new Calculation(plugin,
246 x + title->get_w() + 10,
248 calculation->create_objects();
256 void MotionWindow::update_mode()
258 for(int i = 0; i < TOTAL_POINTS; i++)
260 global_range_w[i]->update(plugin->config.global_range_w[i],
263 global_range_h[i]->update(plugin->config.global_range_h[i],
266 vectors[i]->update(plugin->config.draw_vectors[i]);
267 global[i]->update(plugin->config.global[i]);
283 MotionGlobal::MotionGlobal(MotionMain2 *plugin,
294 this->plugin = plugin;
299 int MotionGlobal::handle_event()
301 *value = get_value();
302 plugin->send_configure_change();
307 MotionPot::MotionPot(MotionMain2 *plugin,
319 this->plugin = plugin;
324 int MotionPot::handle_event()
326 *value = (int)get_value();
327 plugin->send_configure_change();
342 GlobalSearchPositions::GlobalSearchPositions(MotionMain2 *plugin,
352 this->plugin = plugin;
354 void GlobalSearchPositions::create_objects()
356 add_item(new BC_MenuItem("16"));
357 add_item(new BC_MenuItem("32"));
358 add_item(new BC_MenuItem("64"));
359 add_item(new BC_MenuItem("128"));
360 add_item(new BC_MenuItem("256"));
361 add_item(new BC_MenuItem("512"));
362 add_item(new BC_MenuItem("1024"));
363 add_item(new BC_MenuItem("2048"));
364 add_item(new BC_MenuItem("4096"));
365 add_item(new BC_MenuItem("8192"));
366 add_item(new BC_MenuItem("16384"));
367 add_item(new BC_MenuItem("32768"));
368 add_item(new BC_MenuItem("65536"));
369 add_item(new BC_MenuItem("131072"));
370 char string[BCTEXTLEN];
371 sprintf(string, "%d", plugin->config.global_positions);
375 int GlobalSearchPositions::handle_event()
377 plugin->config.global_positions = atoi(get_text());
378 plugin->send_configure_change();
393 MotionMagnitude::MotionMagnitude(MotionMain2 *plugin,
398 (int64_t)plugin->config.magnitude,
402 this->plugin = plugin;
405 int MotionMagnitude::handle_event()
407 plugin->config.magnitude = (int)get_value();
408 plugin->send_configure_change();
413 MotionReturnSpeed::MotionReturnSpeed(MotionMain2 *plugin,
418 (int64_t)plugin->config.return_speed,
422 this->plugin = plugin;
425 int MotionReturnSpeed::handle_event()
427 plugin->config.return_speed = (int)get_value();
428 plugin->send_configure_change();
436 MotionBlockX::MotionBlockX(MotionMain2 *plugin,
443 (float)plugin->config.block_x[number],
447 this->plugin = plugin;
449 this->number = number;
452 int MotionBlockX::handle_event()
454 plugin->config.block_x[number] = get_value();
455 gui->block_x_text[number]->update((float)plugin->config.block_x[number]);
456 plugin->send_configure_change();
463 MotionBlockY::MotionBlockY(MotionMain2 *plugin,
470 (float)plugin->config.block_y[number],
474 this->plugin = plugin;
476 this->number = number;
479 int MotionBlockY::handle_event()
481 plugin->config.block_y[number] = get_value();
482 gui->block_y_text[number]->update((float)plugin->config.block_y[number]);
483 plugin->send_configure_change();
487 MotionBlockXText::MotionBlockXText(MotionMain2 *plugin,
496 (float)plugin->config.block_x[number])
498 this->plugin = plugin;
500 this->number = number;
504 int MotionBlockXText::handle_event()
506 plugin->config.block_x[number] = atof(get_text());
507 gui->block_x[number]->update(plugin->config.block_x[number]);
508 plugin->send_configure_change();
515 MotionBlockYText::MotionBlockYText(MotionMain2 *plugin,
524 (float)plugin->config.block_y[number])
526 this->plugin = plugin;
528 this->number = number;
532 int MotionBlockYText::handle_event()
534 plugin->config.block_y[number] = atof(get_text());
535 gui->block_y[number]->update(plugin->config.block_y[number]);
536 plugin->send_configure_change();
555 MotionDrawVectors::MotionDrawVectors(MotionMain2 *plugin,
562 plugin->config.draw_vectors[number],
566 this->plugin = plugin;
567 this->number = number;
570 int MotionDrawVectors::handle_event()
572 plugin->config.draw_vectors[number] = get_value();
573 plugin->send_configure_change();
584 TrackSingleFrame::TrackSingleFrame(MotionMain2 *plugin,
590 plugin->config.tracking_object == MotionScan::TRACK_SINGLE,
591 _("Track single frame"))
593 this->plugin = plugin;
597 int TrackSingleFrame::handle_event()
599 plugin->config.tracking_object = MotionScan::TRACK_SINGLE;
600 gui->track_previous->update(0);
601 gui->previous_same->update(0);
602 gui->track_frame_number->enable();
603 plugin->send_configure_change();
614 TrackFrameNumber::TrackFrameNumber(MotionMain2 *plugin,
618 : BC_TextBox(x, y, 100, 1, plugin->config.track_frame)
620 this->plugin = plugin;
622 if(plugin->config.tracking_object != MotionScan::TRACK_SINGLE) disable();
625 int TrackFrameNumber::handle_event()
627 plugin->config.track_frame = atol(get_text());
628 plugin->send_configure_change();
638 TrackPreviousFrame::TrackPreviousFrame(MotionMain2 *plugin,
644 plugin->config.tracking_object == MotionScan::TRACK_PREVIOUS,
645 _("Track previous frame"))
647 this->plugin = plugin;
650 int TrackPreviousFrame::handle_event()
652 plugin->config.tracking_object = MotionScan::TRACK_PREVIOUS;
653 gui->track_single->update(0);
654 gui->previous_same->update(0);
655 gui->track_frame_number->disable();
656 plugin->send_configure_change();
667 PreviousFrameSameBlock::PreviousFrameSameBlock(MotionMain2 *plugin,
673 plugin->config.tracking_object == MotionScan::PREVIOUS_SAME_BLOCK,
674 _("Previous frame same block"))
676 this->plugin = plugin;
679 int PreviousFrameSameBlock::handle_event()
681 plugin->config.tracking_object = MotionScan::PREVIOUS_SAME_BLOCK;
682 gui->track_single->update(0);
683 gui->track_previous->update(0);
684 gui->track_frame_number->disable();
685 plugin->send_configure_change();
696 MasterLayer::MasterLayer(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
700 to_text(plugin->config.bottom_is_master))
702 this->plugin = plugin;
706 int MasterLayer::handle_event()
708 plugin->config.bottom_is_master = from_text(get_text());
709 plugin->send_configure_change();
713 void MasterLayer::create_objects()
715 add_item(new BC_MenuItem(to_text(0)));
716 add_item(new BC_MenuItem(to_text(1)));
719 int MasterLayer::from_text(char *text)
721 if(!strcmp(text, _("Top"))) return 0;
725 char* MasterLayer::to_text(int mode)
727 return mode ? _("Bottom") : _("Top");
730 int MasterLayer::calculate_w(MotionWindow *gui)
733 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0)));
734 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1)));
745 Action::Action(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
749 to_text(plugin->config.action))
751 this->plugin = plugin;
755 int Action::handle_event()
757 plugin->config.action = from_text(get_text());
758 plugin->send_configure_change();
762 void Action::create_objects()
764 add_item(new BC_MenuItem(to_text(MotionScan::TRACK)));
765 add_item(new BC_MenuItem(to_text(MotionScan::TRACK_PIXEL)));
766 add_item(new BC_MenuItem(to_text(MotionScan::STABILIZE)));
767 add_item(new BC_MenuItem(to_text(MotionScan::STABILIZE_PIXEL)));
768 add_item(new BC_MenuItem(to_text(MotionScan::NOTHING)));
771 int Action::from_text(char *text)
773 if(!strcmp(text, _("Track"))) return MotionScan::TRACK;
774 if(!strcmp(text, _("Track Pixel"))) return MotionScan::TRACK_PIXEL;
775 if(!strcmp(text, _("Stabilize"))) return MotionScan::STABILIZE;
776 if(!strcmp(text, _("Stabilize Pixel"))) return MotionScan::STABILIZE_PIXEL;
777 if(!strcmp(text, _("Do Nothing"))) return MotionScan::NOTHING;
781 char* Action::to_text(int mode)
785 case MotionScan::TRACK:
788 case MotionScan::TRACK_PIXEL:
789 return _("Track Pixel");
791 case MotionScan::STABILIZE:
792 return _("Stabilize");
794 case MotionScan::STABILIZE_PIXEL:
795 return _("Stabilize Pixel");
797 case MotionScan::NOTHING:
798 return _("Do Nothing");
806 int Action::calculate_w(MotionWindow *gui)
809 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::TRACK)));
810 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::TRACK_PIXEL)));
811 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::STABILIZE)));
812 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::STABILIZE_PIXEL)));
813 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::NOTHING)));
821 Calculation::Calculation(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
825 to_text(plugin->config.calculation))
827 this->plugin = plugin;
831 int Calculation::handle_event()
833 plugin->config.calculation = from_text(get_text());
834 plugin->send_configure_change();
838 void Calculation::create_objects()
840 add_item(new BC_MenuItem(to_text(MotionScan::NO_CALCULATE)));
841 add_item(new BC_MenuItem(to_text(MotionScan::CALCULATE)));
842 add_item(new BC_MenuItem(to_text(MotionScan::SAVE)));
843 add_item(new BC_MenuItem(to_text(MotionScan::LOAD)));
846 int Calculation::from_text(char *text)
848 if(!strcmp(text, _("Don't Calculate"))) return MotionScan::NO_CALCULATE;
849 if(!strcmp(text, _("Recalculate"))) return MotionScan::CALCULATE;
850 if(!strcmp(text, _("Save coords to /tmp"))) return MotionScan::SAVE;
851 if(!strcmp(text, _("Load coords from /tmp"))) return MotionScan::LOAD;
855 char* Calculation::to_text(int mode)
859 case MotionScan::NO_CALCULATE:
860 return _("Don't Calculate");
862 case MotionScan::CALCULATE:
863 return _("Recalculate");
865 case MotionScan::SAVE:
866 return _("Save coords to /tmp");
868 case MotionScan::LOAD:
869 return _("Load coords from /tmp");
877 int Calculation::calculate_w(MotionWindow *gui)
880 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::NO_CALCULATE)));
881 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::CALCULATE)));
882 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::SAVE)));
883 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::LOAD)));
896 TrackingDirection::TrackingDirection(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
900 to_text(plugin->config.horizontal_only, plugin->config.vertical_only))
902 this->plugin = plugin;
906 int TrackingDirection::handle_event()
908 from_text(&plugin->config.horizontal_only, &plugin->config.vertical_only, get_text());
909 plugin->send_configure_change();
913 void TrackingDirection::create_objects()
915 add_item(new BC_MenuItem(to_text(1, 0)));
916 add_item(new BC_MenuItem(to_text(0, 1)));
917 add_item(new BC_MenuItem(to_text(0, 0)));
920 void TrackingDirection::from_text(int *horizontal_only, int *vertical_only, char *text)
922 *horizontal_only = 0;
924 if(!strcmp(text, to_text(1, 0))) *horizontal_only = 1;
925 if(!strcmp(text, to_text(0, 1))) *vertical_only = 1;
928 char* TrackingDirection::to_text(int horizontal_only, int vertical_only)
930 if(horizontal_only) return _("Horizontal only");
931 if(vertical_only) return _("Vertical only");
935 int TrackingDirection::calculate_w(MotionWindow *gui)
938 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1, 0)));
939 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 1)));
940 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 0)));