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, xS(680), yS(660), xS(680), yS(660), 0)
42 this->plugin = plugin;
45 MotionWindow::~MotionWindow()
49 void MotionWindow::create_objects()
51 int xs10 = xS(10), xs20 = xS(20), xs120 = xS(120);
52 int ys10 = yS(10), ys20 = yS(20), ys30 = yS(30), ys40 = yS(40), ys50 = yS(50);
53 int x1[] = { 10, get_w()/2 };
54 int x = xs10, y = ys10, y1 = ys10;
58 for(int i = 0; i < TOTAL_POINTS; i++)
61 char *global_title[] =
66 add_subwindow(global[i] = new MotionGlobal(plugin,
70 &plugin->config.global[i],
74 add_subwindow(title = new BC_Title(x1[i],
76 _("Translation search radius:\n(W/H Percent of image)")));
77 add_subwindow(global_range_w[i] = new MotionPot(plugin,
78 x1[i] + title->get_w() + xs10,
80 &plugin->config.global_range_w[i],
83 add_subwindow(global_range_h[i] = new MotionPot(plugin,
84 x1[i] + title->get_w() + xs10 + global_range_w[i]->get_w(),
86 &plugin->config.global_range_h[i],
92 add_subwindow(title = new BC_Title(x1[i],
94 _("Translation search offset:\n(X/Y Percent of image)")));
95 add_subwindow(global_origin_x[i] = new MotionPot(plugin,
96 x1[i] + title->get_w() + xs10,
98 &plugin->config.global_origin_x[i],
101 add_subwindow(global_origin_y[i] = new MotionPot(plugin,
102 x1[i] + title->get_w() + xs10 + global_origin_x[i]->get_w(),
104 &plugin->config.global_origin_y[i],
109 add_subwindow(title = new BC_Title(x1[i],
111 _("Translation block size:\n(W/H Percent of image)")));
112 add_subwindow(global_block_w[i] = new MotionPot(plugin,
113 x1[i] + title->get_w() + xs10,
115 &plugin->config.global_block_w[i],
118 add_subwindow(global_block_h[i] = new MotionPot(plugin,
119 x1[i] + title->get_w() + xs10 + global_block_w[i]->get_w(),
121 &plugin->config.global_block_h[i],
127 add_subwindow(title = new BC_Title(x1[i], y + ys10, _("Block X:")));
128 add_subwindow(block_x[i] = new MotionBlockX(plugin,
130 x1[i] + title->get_w() + xs10,
133 add_subwindow(block_x_text[i] = new MotionBlockXText(plugin,
135 x1[i] + title->get_w() + xs10 + block_x[i]->get_w() + xs10,
140 add_subwindow(title = new BC_Title(x1[i], y + ys10, _("Block Y:")));
141 add_subwindow(block_y[i] = new MotionBlockY(plugin,
143 x1[i] + title->get_w() + xs10,
146 add_subwindow(block_y_text[i] = new MotionBlockYText(plugin,
148 x1[i] + title->get_w() + xs10 + block_y[i]->get_w() + xs10,
154 add_subwindow(vectors[i] = new MotionDrawVectors(plugin,
163 add_subwindow(new BC_Bar(x, y, get_w() - x * 2));
165 add_subwindow(title = new BC_Title(x, y, _("Search steps:")));
166 add_subwindow(global_search_positions = new GlobalSearchPositions(plugin,
167 x + title->get_w() + xs10, y, xs120));
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() + xs10,
176 tracking_direction->create_objects();
179 add_subwindow(title = new BC_Title(x, y + ys10, _("Maximum absolute offset:")));
180 add_subwindow(magnitude = new MotionMagnitude(plugin,
181 x + title->get_w() + xs10,
185 add_subwindow(title = new BC_Title(x, y + ys10, _("Settling speed:")));
186 add_subwindow(return_speed = new MotionReturnSpeed(plugin,
187 x + title->get_w() + xs10,
192 add_subwindow(track_single = new TrackSingleFrame(plugin,
196 add_subwindow(title = new BC_Title(x + track_single->get_w() + xs20,
198 _("Frame number:")));
199 add_subwindow(track_frame_number = new TrackFrameNumber(plugin,
201 x + track_single->get_w() + title->get_w() + xs20,
203 if(plugin->config.tracking_object != MotionScan::TRACK_SINGLE)
204 track_frame_number->disable();
207 add_subwindow(track_previous = new TrackPreviousFrame(plugin,
213 add_subwindow(previous_same = new PreviousFrameSameBlock(plugin,
220 add_subwindow(title = new BC_Title(x, y, _("Master layer:")));
221 add_subwindow(master_layer = new MasterLayer(plugin,
223 x + title->get_w() + xs10,
225 master_layer->create_objects();
229 add_subwindow(title = new BC_Title(x, y, _("Action:")));
230 add_subwindow(action = new Action(plugin,
232 x + title->get_w() + xs10,
234 action->create_objects();
240 add_subwindow(title = new BC_Title(x, y, _("Calculation:")));
241 add_subwindow(calculation = new Calculation(plugin,
243 x + title->get_w() + xs10,
245 calculation->create_objects();
253 void MotionWindow::update_mode()
255 for(int i = 0; i < TOTAL_POINTS; i++)
257 global_range_w[i]->update(plugin->config.global_range_w[i],
260 global_range_h[i]->update(plugin->config.global_range_h[i],
263 vectors[i]->update(plugin->config.draw_vectors[i]);
264 global[i]->update(plugin->config.global[i]);
280 MotionGlobal::MotionGlobal(MotionMain2 *plugin,
291 this->plugin = plugin;
296 int MotionGlobal::handle_event()
298 *value = get_value();
299 plugin->send_configure_change();
304 MotionPot::MotionPot(MotionMain2 *plugin,
316 this->plugin = plugin;
321 int MotionPot::handle_event()
323 *value = (int)get_value();
324 plugin->send_configure_change();
339 GlobalSearchPositions::GlobalSearchPositions(MotionMain2 *plugin,
349 this->plugin = plugin;
351 void GlobalSearchPositions::create_objects()
353 add_item(new BC_MenuItem("16"));
354 add_item(new BC_MenuItem("32"));
355 add_item(new BC_MenuItem("64"));
356 add_item(new BC_MenuItem("128"));
357 add_item(new BC_MenuItem("256"));
358 add_item(new BC_MenuItem("512"));
359 add_item(new BC_MenuItem("1024"));
360 add_item(new BC_MenuItem("2048"));
361 add_item(new BC_MenuItem("4096"));
362 add_item(new BC_MenuItem("8192"));
363 add_item(new BC_MenuItem("16384"));
364 add_item(new BC_MenuItem("32768"));
365 add_item(new BC_MenuItem("65536"));
366 add_item(new BC_MenuItem("131072"));
367 char string[BCTEXTLEN];
368 sprintf(string, "%d", plugin->config.global_positions);
372 int GlobalSearchPositions::handle_event()
374 plugin->config.global_positions = atoi(get_text());
375 plugin->send_configure_change();
390 MotionMagnitude::MotionMagnitude(MotionMain2 *plugin,
395 (int64_t)plugin->config.magnitude,
399 this->plugin = plugin;
402 int MotionMagnitude::handle_event()
404 plugin->config.magnitude = (int)get_value();
405 plugin->send_configure_change();
410 MotionReturnSpeed::MotionReturnSpeed(MotionMain2 *plugin,
415 (int64_t)plugin->config.return_speed,
419 this->plugin = plugin;
422 int MotionReturnSpeed::handle_event()
424 plugin->config.return_speed = (int)get_value();
425 plugin->send_configure_change();
433 MotionBlockX::MotionBlockX(MotionMain2 *plugin,
440 (float)plugin->config.block_x[number],
444 this->plugin = plugin;
446 this->number = number;
449 int MotionBlockX::handle_event()
451 plugin->config.block_x[number] = get_value();
452 gui->block_x_text[number]->update((float)plugin->config.block_x[number]);
453 plugin->send_configure_change();
460 MotionBlockY::MotionBlockY(MotionMain2 *plugin,
467 (float)plugin->config.block_y[number],
471 this->plugin = plugin;
473 this->number = number;
476 int MotionBlockY::handle_event()
478 plugin->config.block_y[number] = get_value();
479 gui->block_y_text[number]->update((float)plugin->config.block_y[number]);
480 plugin->send_configure_change();
484 MotionBlockXText::MotionBlockXText(MotionMain2 *plugin,
489 : BC_TextBox(x, y, xS(75), 1,
490 (float)plugin->config.block_x[number])
492 this->plugin = plugin;
494 this->number = number;
498 int MotionBlockXText::handle_event()
500 plugin->config.block_x[number] = atof(get_text());
501 gui->block_x[number]->update(plugin->config.block_x[number]);
502 plugin->send_configure_change();
509 MotionBlockYText::MotionBlockYText(MotionMain2 *plugin,
514 : BC_TextBox(x, y, xS(75), 1,
515 (float)plugin->config.block_y[number])
517 this->plugin = plugin;
519 this->number = number;
523 int MotionBlockYText::handle_event()
525 plugin->config.block_y[number] = atof(get_text());
526 gui->block_y[number]->update(plugin->config.block_y[number]);
527 plugin->send_configure_change();
546 MotionDrawVectors::MotionDrawVectors(MotionMain2 *plugin,
553 plugin->config.draw_vectors[number],
557 this->plugin = plugin;
558 this->number = number;
561 int MotionDrawVectors::handle_event()
563 plugin->config.draw_vectors[number] = get_value();
564 plugin->send_configure_change();
575 TrackSingleFrame::TrackSingleFrame(MotionMain2 *plugin,
581 plugin->config.tracking_object == MotionScan::TRACK_SINGLE,
582 _("Track single frame"))
584 this->plugin = plugin;
588 int TrackSingleFrame::handle_event()
590 plugin->config.tracking_object = MotionScan::TRACK_SINGLE;
591 gui->track_previous->update(0);
592 gui->previous_same->update(0);
593 gui->track_frame_number->enable();
594 plugin->send_configure_change();
605 TrackFrameNumber::TrackFrameNumber(MotionMain2 *plugin,
609 : BC_TextBox(x, y, xS(100), 1, plugin->config.track_frame)
611 this->plugin = plugin;
615 int TrackFrameNumber::handle_event()
617 plugin->config.track_frame = atol(get_text());
618 plugin->send_configure_change();
628 TrackPreviousFrame::TrackPreviousFrame(MotionMain2 *plugin,
634 plugin->config.tracking_object == MotionScan::TRACK_PREVIOUS,
635 _("Track previous frame"))
637 this->plugin = plugin;
640 int TrackPreviousFrame::handle_event()
642 plugin->config.tracking_object = MotionScan::TRACK_PREVIOUS;
643 gui->track_single->update(0);
644 gui->previous_same->update(0);
645 gui->track_frame_number->disable();
646 plugin->send_configure_change();
657 PreviousFrameSameBlock::PreviousFrameSameBlock(MotionMain2 *plugin,
663 plugin->config.tracking_object == MotionScan::PREVIOUS_SAME_BLOCK,
664 _("Previous frame same block"))
666 this->plugin = plugin;
669 int PreviousFrameSameBlock::handle_event()
671 plugin->config.tracking_object = MotionScan::PREVIOUS_SAME_BLOCK;
672 gui->track_single->update(0);
673 gui->track_previous->update(0);
674 gui->track_frame_number->disable();
675 plugin->send_configure_change();
686 MasterLayer::MasterLayer(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
690 to_text(plugin->config.bottom_is_master))
692 this->plugin = plugin;
696 int MasterLayer::handle_event()
698 plugin->config.bottom_is_master = from_text(get_text());
699 plugin->send_configure_change();
703 void MasterLayer::create_objects()
705 add_item(new BC_MenuItem(to_text(0)));
706 add_item(new BC_MenuItem(to_text(1)));
709 int MasterLayer::from_text(char *text)
711 if(!strcmp(text, _("Top"))) return 0;
715 char* MasterLayer::to_text(int mode)
717 return mode ? _("Bottom") : _("Top");
720 int MasterLayer::calculate_w(MotionWindow *gui)
723 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0)));
724 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1)));
725 return result + xS(80);
735 Action::Action(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
739 to_text(plugin->config.action))
741 this->plugin = plugin;
745 int Action::handle_event()
747 plugin->config.action = from_text(get_text());
748 plugin->send_configure_change();
752 void Action::create_objects()
754 add_item(new BC_MenuItem(to_text(MotionScan::TRACK)));
755 add_item(new BC_MenuItem(to_text(MotionScan::TRACK_PIXEL)));
756 add_item(new BC_MenuItem(to_text(MotionScan::STABILIZE)));
757 add_item(new BC_MenuItem(to_text(MotionScan::STABILIZE_PIXEL)));
758 add_item(new BC_MenuItem(to_text(MotionScan::NOTHING)));
761 int Action::from_text(char *text)
763 if(!strcmp(text, _("Track"))) return MotionScan::TRACK;
764 if(!strcmp(text, _("Track Pixel"))) return MotionScan::TRACK_PIXEL;
765 if(!strcmp(text, _("Stabilize"))) return MotionScan::STABILIZE;
766 if(!strcmp(text, _("Stabilize Pixel"))) return MotionScan::STABILIZE_PIXEL;
767 if(!strcmp(text, _("Do Nothing"))) return MotionScan::NOTHING;
771 char* Action::to_text(int mode)
775 case MotionScan::TRACK:
778 case MotionScan::TRACK_PIXEL:
779 return _("Track Pixel");
781 case MotionScan::STABILIZE:
782 return _("Stabilize");
784 case MotionScan::STABILIZE_PIXEL:
785 return _("Stabilize Pixel");
787 case MotionScan::NOTHING:
788 return _("Do Nothing");
796 int Action::calculate_w(MotionWindow *gui)
799 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::TRACK)));
800 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::TRACK_PIXEL)));
801 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::STABILIZE)));
802 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::STABILIZE_PIXEL)));
803 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::NOTHING)));
804 return result + xS(80);
811 Calculation::Calculation(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
815 to_text(plugin->config.calculation))
817 this->plugin = plugin;
821 int Calculation::handle_event()
823 plugin->config.calculation = from_text(get_text());
824 plugin->send_configure_change();
828 void Calculation::create_objects()
830 add_item(new BC_MenuItem(to_text(MotionScan::NO_CALCULATE)));
831 add_item(new BC_MenuItem(to_text(MotionScan::CALCULATE)));
832 add_item(new BC_MenuItem(to_text(MotionScan::SAVE)));
833 add_item(new BC_MenuItem(to_text(MotionScan::LOAD)));
836 int Calculation::from_text(char *text)
838 if(!strcmp(text, _("Don't Calculate"))) return MotionScan::NO_CALCULATE;
839 if(!strcmp(text, _("Recalculate"))) return MotionScan::CALCULATE;
840 if(!strcmp(text, _("Save coords to /tmp"))) return MotionScan::SAVE;
841 if(!strcmp(text, _("Load coords from /tmp"))) return MotionScan::LOAD;
845 char* Calculation::to_text(int mode)
849 case MotionScan::NO_CALCULATE:
850 return _("Don't Calculate");
852 case MotionScan::CALCULATE:
853 return _("Recalculate");
855 case MotionScan::SAVE:
856 return _("Save coords to /tmp");
858 case MotionScan::LOAD:
859 return _("Load coords from /tmp");
867 int Calculation::calculate_w(MotionWindow *gui)
870 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::NO_CALCULATE)));
871 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::CALCULATE)));
872 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::SAVE)));
873 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionScan::LOAD)));
874 return result + xS(80);
886 TrackingDirection::TrackingDirection(MotionMain2 *plugin, MotionWindow *gui, int x, int y)
890 to_text(plugin->config.horizontal_only, plugin->config.vertical_only))
892 this->plugin = plugin;
896 int TrackingDirection::handle_event()
898 from_text(&plugin->config.horizontal_only, &plugin->config.vertical_only, get_text());
899 plugin->send_configure_change();
903 void TrackingDirection::create_objects()
905 add_item(new BC_MenuItem(to_text(1, 0)));
906 add_item(new BC_MenuItem(to_text(0, 1)));
907 add_item(new BC_MenuItem(to_text(0, 0)));
910 void TrackingDirection::from_text(int *horizontal_only, int *vertical_only, char *text)
912 *horizontal_only = 0;
914 if(!strcmp(text, to_text(1, 0))) *horizontal_only = 1;
915 if(!strcmp(text, to_text(0, 1))) *vertical_only = 1;
918 char* TrackingDirection::to_text(int horizontal_only, int vertical_only)
920 if(horizontal_only) return _("Horizontal only");
921 if(vertical_only) return _("Vertical only");
925 int TrackingDirection::calculate_w(MotionWindow *gui)
928 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1, 0)));
929 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 1)));
930 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 0)));
931 return result + xS(80);