add xvid/flv formats, add motion plugin varients + save file, fix build bug
[goodguy/history.git] / cinelerra-5.1 / plugins / motion-cv / motionwindow-cv.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * 
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.
10  * 
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.
15  * 
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
19  * 
20  */
21
22 #include "bcdisplayinfo.h"
23 #include "clip.h"
24 #include "language.h"
25 #include "motion-cv.h"
26 #include "motionwindow-cv.h"
27
28
29
30
31
32
33
34
35
36 MotionCVWindow::MotionCVWindow(MotionCVMain *plugin)
37  : PluginClientWindow(plugin, 815, 650, 815, 650, 0)
38 {
39         this->plugin = plugin; 
40 }
41
42 MotionCVWindow::~MotionCVWindow()
43 {
44 }
45
46 void MotionCVWindow::create_objects()
47 {
48         int x1 = 10, x = 10, y = 10;
49         int x2 = 410;
50         BC_Title *title;
51
52
53
54         add_subwindow(global = new MotionCVGlobal(plugin,
55                 this,
56                 x1,
57                 y));
58
59         add_subwindow(rotate = new MotionCVRotate(plugin,
60                 this,
61                 x2,
62                 y));
63         y += 50;
64
65         add_subwindow(title = new BC_Title(x1, 
66                 y, 
67                 _("Translation search radius:\n(W/H Percent of image)")));
68         add_subwindow(global_range_w = new GlobalRange(plugin, 
69                 x1 + title->get_w() + 10, 
70                 y,
71                 &plugin->config.global_range_w));
72         add_subwindow(global_range_h = new GlobalRange(plugin, 
73                 x1 + title->get_w() + 30 + global_range_w->get_w(),
74                 y,
75                 &plugin->config.global_range_h));
76
77         add_subwindow(title = new BC_Title(x2, 
78                 y, 
79                 _("Rotation search radius:\n(Degrees)")));
80         add_subwindow(rotation_range = new RotationRange(plugin, 
81                 x2 + title->get_w() + 10, 
82                 y));
83
84         y += 50;
85         add_subwindow(title = new BC_Title(x1, 
86                 y, 
87                 _("Translation block size:\n(W/H Percent of image)")));
88         add_subwindow(global_block_w = new BlockSize(plugin, 
89                 x1 + title->get_w() + 10, 
90                 y,
91                 &plugin->config.global_block_w));
92         add_subwindow(global_block_h = new BlockSize(plugin, 
93                 x1 + title->get_w() + 30 + global_block_w->get_w(),
94                 y,
95                 &plugin->config.global_block_h));
96
97         add_subwindow(title = new BC_Title(x2, 
98                 y, 
99                 _("Rotation block size:\n(W/H Percent of image)")));
100         add_subwindow(rotation_block_w = new BlockSize(plugin, 
101                 x2 + title->get_w() + 10, 
102                 y,
103                 &plugin->config.rotation_block_w));
104         add_subwindow(rotation_block_h = new BlockSize(plugin, 
105                 x2 + title->get_w() + 30 + rotation_block_w->get_w(),
106                 y,
107                 &plugin->config.rotation_block_h));
108
109         y += 50;
110         add_subwindow(title = new BC_Title(x1, y, _("Translation search steps:")));
111         add_subwindow(global_search_positions = new GlobalSearchPositions(plugin, 
112                 x1 + title->get_w() + 10, 
113                 y, 
114                 80));
115         global_search_positions->create_objects();
116
117         add_subwindow(title = new BC_Title(x2, y, _("Rotation search steps:")));
118         add_subwindow(rotation_search_positions = new RotationSearchPositions(plugin, 
119                 x2 + title->get_w() + 10, 
120                 y, 
121                 80));
122         rotation_search_positions->create_objects();
123
124         y += 50;
125         add_subwindow(title = new BC_Title(x, y, _("Translation direction:")));
126         add_subwindow(mode3 = new Mode3(plugin, 
127                 this, 
128                 x + title->get_w() + 10, 
129                 y));
130         mode3->create_objects();
131
132         y += 40;
133         add_subwindow(title = new BC_Title(x, y + 10, _("Block X:")));
134         add_subwindow(block_x = new MotionCVBlockX(plugin, 
135                 this, 
136                 x + title->get_w() + 10, 
137                 y));
138         add_subwindow(block_x_text = new MotionCVBlockXText(plugin, 
139                 this, 
140                 x + title->get_w() + 10 + block_x->get_w() + 10, 
141                 y + 10));
142
143         y += 40;
144         add_subwindow(title = new BC_Title(x, y + 10, _("Block Y:")));
145         add_subwindow(block_y = new MotionCVBlockY(plugin, 
146                 this, 
147                 x + title->get_w() + 10, 
148                 y));
149         add_subwindow(block_y_text = new MotionCVBlockYText(plugin, 
150                 this, 
151                 x + title->get_w() + 10 + block_y->get_w() + 10, 
152                 y + 10));
153
154         y += 50;
155         add_subwindow(title = new BC_Title(x, y + 10, _("Maximum absolute offset:")));
156         add_subwindow(magnitude = new MotionCVMagnitude(plugin, 
157                 x + title->get_w() + 10, 
158                 y));
159
160         y += 40;
161         add_subwindow(title = new BC_Title(x, y + 10, _("Settling speed:")));
162         add_subwindow(return_speed = new MotionCVReturnSpeed(plugin,
163                 x + title->get_w() + 10, 
164                 y));
165
166
167
168         y += 40;
169         add_subwindow(vectors = new MotionCVDrawVectors(plugin,
170                 this,
171                 x,
172                 y));
173
174         add_subwindow(title = new BC_Title(x2, y, _("Tracking file:")));
175         add_subwindow(tracking_file = new MotionCVTrackingFile(plugin,
176                 plugin->config.tracking_file, this, x2+title->get_w() + 20, y));
177
178         y += 40;
179         add_subwindow(track_single = new TrackSingleFrame(plugin, 
180                 this,
181                 x, 
182                 y));
183         add_subwindow(title = new BC_Title(x + track_single->get_w() + 20, 
184                 y, 
185                 _("Frame number:")));
186         add_subwindow(track_frame_number = new TrackFrameNumber(plugin, 
187                 this,
188                 x + track_single->get_w() + title->get_w() + 20, 
189                 y));
190         add_subwindow(addtrackedframeoffset = new AddTrackedFrameOffset(plugin,
191                 this,
192                 x + track_single->get_w() + title->get_w() + 30,
193                 y + track_single->get_h()));
194
195
196         y += 20;
197         add_subwindow(track_previous = new TrackPreviousFrame(plugin, 
198                 this,
199                 x, 
200                 y));
201
202         y += 20;
203         add_subwindow(previous_same = new PreviousFrameSameBlock(plugin, 
204                 this,
205                 x, 
206                 y));
207
208         y += 40;
209         //int y1 = y;
210         add_subwindow(title = new BC_Title(x, y, _("Master layer:")));
211         add_subwindow(master_layer = new MasterLayer(plugin, 
212                 this,
213                 x + title->get_w() + 10, 
214                 y));
215         master_layer->create_objects();
216         y += 30;
217
218
219         add_subwindow(title = new BC_Title(x, y, _("Action:")));
220         add_subwindow(mode1 = new Mode1(plugin, 
221                 this,
222                 x + title->get_w() + 10, 
223                 y));
224         mode1->create_objects();
225         y += 30;
226
227
228
229
230         add_subwindow(title = new BC_Title(x, y, _("Calculation:")));
231         add_subwindow(mode2 = new Mode2(plugin, 
232                 this, 
233                 x + title->get_w() + 10, 
234                 y));
235         mode2->create_objects();
236
237
238
239         show_window(1);
240 }
241
242 void MotionCVWindow::update_mode()
243 {
244         global_range_w->update(plugin->config.global_range_w,
245                 MIN_RADIUS,
246                 MAX_RADIUS);
247         global_range_h->update(plugin->config.global_range_h,
248                 MIN_RADIUS,
249                 MAX_RADIUS);
250         rotation_range->update(plugin->config.rotation_range,
251                 MIN_ROTATION,
252                 MAX_ROTATION);
253         vectors->update(plugin->config.draw_vectors);
254         tracking_file->update(plugin->config.tracking_file);
255         global->update(plugin->config.global);
256         rotate->update(plugin->config.rotate);
257         addtrackedframeoffset->update(plugin->config.addtrackedframeoffset);
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271 GlobalRange::GlobalRange(MotionCVMain *plugin, 
272         int x, 
273         int y,
274         int *value)
275  : BC_IPot(x, 
276                 y, 
277                 (int64_t)*value,
278                 (int64_t)MIN_RADIUS,
279                 (int64_t)MAX_RADIUS)
280 {
281         this->plugin = plugin;
282         this->value = value;
283 }
284
285
286 int GlobalRange::handle_event()
287 {
288         *value = (int)get_value();
289         plugin->send_configure_change();
290         return 1;
291 }
292
293
294
295
296 RotationRange::RotationRange(MotionCVMain *plugin, 
297         int x, 
298         int y)
299  : BC_IPot(x, 
300                 y, 
301                 (int64_t)plugin->config.rotation_range,
302                 (int64_t)MIN_ROTATION,
303                 (int64_t)MAX_ROTATION)
304 {
305         this->plugin = plugin;
306 }
307
308
309 int RotationRange::handle_event()
310 {
311         plugin->config.rotation_range = (int)get_value();
312         plugin->send_configure_change();
313         return 1;
314 }
315
316
317
318
319
320
321
322
323 BlockSize::BlockSize(MotionCVMain *plugin, 
324         int x, 
325         int y,
326         int *value)
327  : BC_IPot(x, 
328                 y, 
329                 (int64_t)*value,
330                 (int64_t)MIN_BLOCK,
331                 (int64_t)MAX_BLOCK)
332 {
333         this->plugin = plugin;
334         this->value = value;
335 }
336
337
338 int BlockSize::handle_event()
339 {
340         *value = (int)get_value();
341         plugin->send_configure_change();
342         return 1;
343 }
344
345
346
347
348
349
350
351
352
353
354
355
356
357 GlobalSearchPositions::GlobalSearchPositions(MotionCVMain *plugin, 
358         int x, 
359         int y,
360         int w)
361  : BC_PopupMenu(x,
362         y,
363         w,
364         "",
365         1)
366 {
367         this->plugin = plugin;
368 }
369 void GlobalSearchPositions::create_objects()
370 {
371         add_item(new BC_MenuItem("64"));
372         add_item(new BC_MenuItem("128"));
373         add_item(new BC_MenuItem("256"));
374         add_item(new BC_MenuItem("512"));
375         add_item(new BC_MenuItem("1024"));
376         add_item(new BC_MenuItem("2048"));
377         add_item(new BC_MenuItem("4096"));
378         add_item(new BC_MenuItem("8192"));
379         add_item(new BC_MenuItem("16384"));
380         add_item(new BC_MenuItem("32768"));
381         add_item(new BC_MenuItem("65536"));
382         add_item(new BC_MenuItem("131072"));
383         char string[BCTEXTLEN];
384         sprintf(string, "%d", plugin->config.global_positions);
385         set_text(string);
386 }
387
388 int GlobalSearchPositions::handle_event()
389 {
390         plugin->config.global_positions = atoi(get_text());
391         plugin->send_configure_change();
392         return 1;
393 }
394
395
396
397
398
399
400
401 RotationSearchPositions::RotationSearchPositions(MotionCVMain *plugin, 
402         int x, 
403         int y,
404         int w)
405  : BC_PopupMenu(x,
406         y,
407         w,
408         "",
409         1)
410 {
411         this->plugin = plugin;
412 }
413 void RotationSearchPositions::create_objects()
414 {
415         add_item(new BC_MenuItem("4"));
416         add_item(new BC_MenuItem("8"));
417         add_item(new BC_MenuItem("16"));
418         add_item(new BC_MenuItem("32"));
419         char string[BCTEXTLEN];
420         sprintf(string, "%d", plugin->config.rotate_positions);
421         set_text(string);
422 }
423
424 int RotationSearchPositions::handle_event()
425 {
426         plugin->config.rotate_positions = atoi(get_text());
427         plugin->send_configure_change();
428         return 1;
429 }
430
431
432
433
434
435
436
437
438 MotionCVMagnitude::MotionCVMagnitude(MotionCVMain *plugin, 
439         int x, 
440         int y)
441  : BC_IPot(x, 
442                 y, 
443                 (int64_t)plugin->config.magnitude,
444                 (int64_t)0,
445                 (int64_t)100)
446 {
447         this->plugin = plugin;
448 }
449
450 int MotionCVMagnitude::handle_event()
451 {
452         plugin->config.magnitude = (int)get_value();
453         plugin->send_configure_change();
454         return 1;
455 }
456
457
458 MotionCVReturnSpeed::MotionCVReturnSpeed(MotionCVMain *plugin, 
459         int x, 
460         int y)
461  : BC_IPot(x, 
462                 y, 
463                 (int64_t)plugin->config.return_speed,
464                 (int64_t)0,
465                 (int64_t)100)
466 {
467         this->plugin = plugin;
468 }
469
470 int MotionCVReturnSpeed::handle_event()
471 {
472         plugin->config.return_speed = (int)get_value();
473         plugin->send_configure_change();
474         return 1;
475 }
476
477
478
479 AddTrackedFrameOffset::AddTrackedFrameOffset(MotionCVMain *plugin, 
480         MotionCVWindow *gui,
481         int x, 
482         int y)
483  : BC_CheckBox(x, 
484         y, 
485         plugin->config.addtrackedframeoffset,
486         _("Add (loaded) offset from tracked frame"))
487 {
488         this->plugin = plugin;
489         this->gui = gui;
490 }
491
492 int AddTrackedFrameOffset::handle_event()
493 {
494         plugin->config.addtrackedframeoffset = get_value();
495         plugin->send_configure_change();
496         return 1;
497 }
498
499 MotionCVTrackingFile::MotionCVTrackingFile(MotionCVMain *plugin,
500         const char *filename, MotionCVWindow *gui, int x, int y)
501  : BC_TextBox(x, y, 250, 1, filename)
502 {
503         this->plugin = plugin;
504         this->gui = gui;
505 };
506
507 int MotionCVTrackingFile::handle_event()
508 {
509         strcpy(plugin->config.tracking_file, get_text());
510         plugin->send_configure_change();
511         return 1;
512 }
513
514 MotionCVGlobal::MotionCVGlobal(MotionCVMain *plugin, 
515         MotionCVWindow *gui,
516         int x, 
517         int y)
518  : BC_CheckBox(x, 
519         y, 
520         plugin->config.global,
521         _("Track translation"))
522 {
523         this->plugin = plugin;
524         this->gui = gui;
525 }
526
527 int MotionCVGlobal::handle_event()
528 {
529         plugin->config.global = get_value();
530         plugin->send_configure_change();
531         return 1;
532 }
533
534 MotionCVRotate::MotionCVRotate(MotionCVMain *plugin, 
535         MotionCVWindow *gui,
536         int x, 
537         int y)
538  : BC_CheckBox(x, 
539         y, 
540         plugin->config.rotate,
541         _("Track rotation"))
542 {
543         this->plugin = plugin;
544         this->gui = gui;
545 }
546
547 int MotionCVRotate::handle_event()
548 {
549         plugin->config.rotate = get_value();
550         plugin->send_configure_change();
551         return 1;
552 }
553
554
555
556
557
558 MotionCVBlockX::MotionCVBlockX(MotionCVMain *plugin, 
559         MotionCVWindow *gui,
560         int x, 
561         int y)
562  : BC_FPot(x,
563         y,
564         plugin->config.block_x,
565         (float)0, 
566         (float)100)
567 {
568         this->plugin = plugin;
569         this->gui = gui;
570 }
571
572 int MotionCVBlockX::handle_event()
573 {
574         plugin->config.block_x = get_value();
575         gui->block_x_text->update((float)plugin->config.block_x);
576         plugin->send_configure_change();
577         return 1;
578 }
579
580
581
582
583 MotionCVBlockY::MotionCVBlockY(MotionCVMain *plugin, 
584         MotionCVWindow *gui,
585         int x, 
586         int y)
587  : BC_FPot(x,
588         y,
589         (float)plugin->config.block_y,
590         (float)0, 
591         (float)100)
592 {
593         this->plugin = plugin;
594         this->gui = gui;
595 }
596
597 int MotionCVBlockY::handle_event()
598 {
599         plugin->config.block_y = get_value();
600         gui->block_y_text->update((float)plugin->config.block_y);
601         plugin->send_configure_change();
602         return 1;
603 }
604
605 MotionCVBlockXText::MotionCVBlockXText(MotionCVMain *plugin, 
606         MotionCVWindow *gui,
607         int x, 
608         int y)
609  : BC_TextBox(x,
610         y,
611         75,
612         1,
613         (float)plugin->config.block_x)
614 {
615         this->plugin = plugin;
616         this->gui = gui;
617         set_precision(4);
618 }
619
620 int MotionCVBlockXText::handle_event()
621 {
622         plugin->config.block_x = atof(get_text());
623         gui->block_x->update(plugin->config.block_x);
624         plugin->send_configure_change();
625         return 1;
626 }
627
628
629
630
631 MotionCVBlockYText::MotionCVBlockYText(MotionCVMain *plugin, 
632         MotionCVWindow *gui,
633         int x, 
634         int y)
635  : BC_TextBox(x,
636         y,
637         75,
638         1,
639         (float)plugin->config.block_y)
640 {
641         this->plugin = plugin;
642         this->gui = gui;
643         set_precision(4);
644 }
645
646 int MotionCVBlockYText::handle_event()
647 {
648         plugin->config.block_y = atof(get_text());
649         gui->block_y->update(plugin->config.block_y);
650         plugin->send_configure_change();
651         return 1;
652 }
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669 MotionCVDrawVectors::MotionCVDrawVectors(MotionCVMain *plugin, 
670         MotionCVWindow *gui,
671         int x, 
672         int y)
673  : BC_CheckBox(x,
674         y, 
675         plugin->config.draw_vectors,
676         _("Draw vectors"))
677 {
678         this->gui = gui;
679         this->plugin = plugin;
680 }
681
682 int MotionCVDrawVectors::handle_event()
683 {
684         plugin->config.draw_vectors = get_value();
685         plugin->send_configure_change();
686         return 1;
687 }
688
689
690
691
692
693
694
695
696 TrackSingleFrame::TrackSingleFrame(MotionCVMain *plugin, 
697         MotionCVWindow *gui,
698         int x, 
699         int y)
700  : BC_Radial(x, 
701         y, 
702         plugin->config.mode3 == MotionCVConfig::TRACK_SINGLE, 
703         _("Track single frame"))
704 {
705         this->plugin = plugin;
706         this->gui = gui;
707 }
708
709 int TrackSingleFrame::handle_event()
710 {
711         plugin->config.mode3 = MotionCVConfig::TRACK_SINGLE;
712         gui->track_previous->update(0);
713         gui->previous_same->update(0);
714         gui->track_frame_number->enable();
715         plugin->send_configure_change();
716         return 1;
717 }
718
719
720
721
722
723
724
725
726 TrackFrameNumber::TrackFrameNumber(MotionCVMain *plugin, 
727         MotionCVWindow *gui,
728         int x, 
729         int y)
730  : BC_TextBox(x, y, 100, 1, plugin->config.track_frame)
731 {
732         this->plugin = plugin;
733         this->gui = gui;
734         if(plugin->config.mode3 != MotionCVConfig::TRACK_SINGLE) disable();
735 }
736
737 int TrackFrameNumber::handle_event()
738 {
739         plugin->config.track_frame = atol(get_text());
740         plugin->send_configure_change();
741         return 1;
742 }
743
744
745
746
747
748
749
750 TrackPreviousFrame::TrackPreviousFrame(MotionCVMain *plugin, 
751         MotionCVWindow *gui,
752         int x, 
753         int y)
754  : BC_Radial(x, 
755         y, 
756         plugin->config.mode3 == MotionCVConfig::TRACK_PREVIOUS, 
757         _("Track previous frame"))
758 {
759         this->plugin = plugin;
760         this->gui = gui;
761 }
762 int TrackPreviousFrame::handle_event()
763 {
764         plugin->config.mode3 = MotionCVConfig::TRACK_PREVIOUS;
765         gui->track_single->update(0);
766         gui->previous_same->update(0);
767         gui->track_frame_number->disable();
768         plugin->send_configure_change();
769         return 1;
770 }
771
772
773
774
775
776
777
778
779 PreviousFrameSameBlock::PreviousFrameSameBlock(MotionCVMain *plugin, 
780         MotionCVWindow *gui,
781         int x, 
782         int y)
783  : BC_Radial(x, 
784         y, 
785         plugin->config.mode3 == MotionCVConfig::PREVIOUS_SAME_BLOCK, 
786         _("Previous frame same block"))
787 {
788         this->plugin = plugin;
789         this->gui = gui;
790 }
791 int PreviousFrameSameBlock::handle_event()
792 {
793         plugin->config.mode3 = MotionCVConfig::PREVIOUS_SAME_BLOCK;
794         gui->track_single->update(0);
795         gui->track_previous->update(0);
796         gui->track_frame_number->disable();
797         plugin->send_configure_change();
798         return 1;
799 }
800
801
802
803
804
805
806
807
808 MasterLayer::MasterLayer(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
809  : BC_PopupMenu(x, y, calculate_w(gui),
810                 to_text(plugin->config.bottom_is_master))
811 {
812         this->plugin = plugin;
813         this->gui = gui;
814 }
815
816 int MasterLayer::handle_event()
817 {
818         plugin->config.bottom_is_master = from_text(get_text());
819         plugin->send_configure_change();
820         return 1;
821 }
822
823 void MasterLayer::create_objects()
824 {
825         add_item(new BC_MenuItem(to_text(0)));
826         add_item(new BC_MenuItem(to_text(1)));
827 }
828
829 int MasterLayer::from_text(char *text)
830 {
831         if(!strcmp(text, _("Top"))) return 0;
832         return 1;
833 }
834
835 const char* MasterLayer::to_text(int mode)
836 {
837         return mode ? _("Bottom") : _("Top");
838 }
839
840 int MasterLayer::calculate_w(MotionCVWindow *gui)
841 {
842         int result = 0;
843         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0)));
844         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1)));
845         return result + 50;
846 }
847
848
849
850
851
852
853
854
855 Mode1::Mode1(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
856  : BC_PopupMenu(x, y, calculate_w(gui),
857                 to_text(plugin->config.mode1))
858 {
859         this->plugin = plugin;
860         this->gui = gui;
861 }
862
863 int Mode1::handle_event()
864 {
865         plugin->config.mode1 = from_text(get_text());
866         plugin->send_configure_change();
867         return 1;
868 }
869
870 void Mode1::create_objects()
871 {
872         add_item(new BC_MenuItem(to_text(MotionCVConfig::TRACK)));
873         add_item(new BC_MenuItem(to_text(MotionCVConfig::TRACK_PIXEL)));
874         add_item(new BC_MenuItem(to_text(MotionCVConfig::STABILIZE)));
875         add_item(new BC_MenuItem(to_text(MotionCVConfig::STABILIZE_PIXEL)));
876         add_item(new BC_MenuItem(to_text(MotionCVConfig::NOTHING)));
877 }
878
879 int Mode1::from_text(char *text)
880 {
881         if(!strcmp(text, _("Track Subpixel"))) return MotionCVConfig::TRACK;
882         if(!strcmp(text, _("Track Pixel"))) return MotionCVConfig::TRACK_PIXEL;
883         if(!strcmp(text, _("Stabilize Subpixel"))) return MotionCVConfig::STABILIZE;
884         if(!strcmp(text, _("Stabilize Pixel"))) return MotionCVConfig::STABILIZE_PIXEL;
885         //if(!strcmp(text, _("Do Nothing"))) return MotionCVConfig::NOTHING;
886         return MotionCVConfig::NOTHING;
887 }
888
889 const char* Mode1::to_text(int mode)
890 {
891         switch(mode) {
892         case MotionCVConfig::TRACK:     return _("Track Subpixel");
893         case MotionCVConfig::TRACK_PIXEL:       return _("Track Pixel");
894         case MotionCVConfig::STABILIZE: return _("Stabilize Subpixel");
895         case MotionCVConfig::STABILIZE_PIXEL: return _("Stabilize Pixel");
896         case MotionCVConfig::NOTHING:   return _("Do Nothing");
897         }
898         return "";
899 }
900
901 int Mode1::calculate_w(MotionCVWindow *gui)
902 {
903         int result = 0;
904         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::TRACK)));
905         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::TRACK_PIXEL)));
906         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::STABILIZE)));
907         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::STABILIZE_PIXEL)));
908         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::NOTHING)));
909         return result + 50;
910 }
911
912
913
914
915
916 Mode2::Mode2(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
917  : BC_PopupMenu(x, y, calculate_w(gui),
918                 to_text(plugin->config.mode2))
919 {
920         this->plugin = plugin;
921         this->gui = gui;
922 }
923
924 int Mode2::handle_event()
925 {
926         plugin->config.mode2 = from_text(get_text());
927         plugin->send_configure_change();
928         return 1;
929 }
930
931 void Mode2::create_objects()
932 {
933         add_item(new BC_MenuItem(to_text(MotionCVConfig::NO_CALCULATE)));
934         add_item(new BC_MenuItem(to_text(MotionCVConfig::RECALCULATE)));
935         add_item(new BC_MenuItem(to_text(MotionCVConfig::SAVE)));
936         add_item(new BC_MenuItem(to_text(MotionCVConfig::LOAD)));
937 }
938
939 int Mode2::from_text(char *text)
940 {
941         if(!strcmp(text, _("Recalculate"))) return MotionCVConfig::RECALCULATE;
942         if(!strcmp(text, _("Save coords to tracking file"))) return MotionCVConfig::SAVE;
943         if(!strcmp(text, _("Load coords from tracking file"))) return MotionCVConfig::LOAD;
944         //if(!strcmp(text, _("Don't Calculate"))) return MotionCVConfig::NO_CALCULATE;
945         return MotionCVConfig::NO_CALCULATE;
946 }
947
948 const char* Mode2::to_text(int mode)
949 {
950         switch(mode) {
951         case MotionCVConfig::NO_CALCULATE: return _("Don't Calculate");
952         case MotionCVConfig::RECALCULATE: return _("Recalculate");
953         case MotionCVConfig::SAVE: return _("Save coords to tracking file");
954         case MotionCVConfig::LOAD: return _("Load coords from tracking file");
955         }
956         return "";
957 }
958
959 int Mode2::calculate_w(MotionCVWindow *gui)
960 {
961         int result = 0;
962         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::NO_CALCULATE)));
963         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::RECALCULATE)));
964         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::SAVE)));
965         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::LOAD)));
966         return result + 50;
967 }
968
969
970
971
972
973
974
975
976
977
978 Mode3::Mode3(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
979  : BC_PopupMenu(x, y, calculate_w(gui),
980                 to_text(plugin->config.horizontal_only, plugin->config.vertical_only))
981 {
982         this->plugin = plugin;
983         this->gui = gui;
984 }
985
986 int Mode3::handle_event()
987 {
988         from_text(&plugin->config.horizontal_only, &plugin->config.vertical_only, get_text());
989         plugin->send_configure_change();
990         return 1;
991 }
992
993 void Mode3::create_objects()
994 {
995         add_item(new BC_MenuItem(to_text(1, 0)));
996         add_item(new BC_MenuItem(to_text(0, 1)));
997         add_item(new BC_MenuItem(to_text(0, 0)));
998 }
999
1000 void Mode3::from_text(int *horizontal_only, int *vertical_only, char *text)
1001 {
1002         *horizontal_only = 0;
1003         *vertical_only = 0;
1004         if(!strcmp(text, to_text(1, 0))) *horizontal_only = 1;
1005         if(!strcmp(text, to_text(0, 1))) *vertical_only = 1;
1006 }
1007
1008 const char* Mode3::to_text(int horizontal_only, int vertical_only)
1009 {
1010         if(horizontal_only) return _("Horizontal only");
1011         if(vertical_only) return _("Vertical only");
1012         return _("Both");
1013 }
1014
1015 int Mode3::calculate_w(MotionCVWindow *gui)
1016 {
1017         int result = 0;
1018         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1, 0)));
1019         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 1)));
1020         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 0)));
1021         return result + 50;
1022 }
1023