remove whitespace at eol
[goodguy/history.git] / cinelerra-5.1 / plugins / motion.new / motionwindow.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.h"
26 #include "motionscan.h"
27 #include "motionwindow.h"
28
29
30
31
32
33
34
35
36
37
38 MotionWindow::MotionWindow(MotionMain *plugin)
39  : PluginClientWindow(plugin,
40         600,
41         650,
42         600,
43         650,
44         0)
45 {
46         this->plugin = plugin;
47 }
48
49 MotionWindow::~MotionWindow()
50 {
51 }
52
53 void MotionWindow::create_objects()
54 {
55         int x1 = 10, x = 10, y = 10;
56         int x2 = 310;
57         BC_Title *title;
58
59
60
61         add_subwindow(global = new MotionGlobal(plugin,
62                 this,
63                 x1,
64                 y));
65
66         add_subwindow(rotate = new MotionRotate(plugin,
67                 this,
68                 x2,
69                 y));
70         y += 50;
71
72         add_subwindow(title = new BC_Title(x1,
73                 y,
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,
77                 y,
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(),
81                 y,
82                 &plugin->config.global_range_h));
83
84         add_subwindow(title = new BC_Title(x2,
85                 y,
86                 _("Rotation search radius:\n(Degrees)")));
87         add_subwindow(rotation_range = new RotationRange(plugin,
88                 x2 + title->get_w() + 10,
89                 y));
90
91         y += 50;
92         add_subwindow(title = new BC_Title(x1,
93                 y,
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,
97                 y,
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(),
101                 y,
102                 &plugin->config.global_block_h));
103
104         add_subwindow(title = new BC_Title(x2,
105                 y,
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,
109                 y,
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(),
113                 y,
114                 &plugin->config.rotation_block_h));
115
116         y += 50;
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,
120                 y,
121                 80));
122         global_search_positions->create_objects();
123
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,
127                 y,
128                 80));
129         rotation_search_positions->create_objects();
130
131         y += 50;
132         add_subwindow(title = new BC_Title(x, y, _("Translation direction:")));
133         add_subwindow(track_direction = new TrackDirection(plugin,
134                 this,
135                 x + title->get_w() + 10,
136                 y));
137         track_direction->create_objects();
138
139         y += 40;
140         add_subwindow(title = new BC_Title(x, y + 10, _("Block X:")));
141         add_subwindow(block_x = new MotionBlockX(plugin,
142                 this,
143                 x + title->get_w() + 10,
144                 y));
145         add_subwindow(block_x_text = new MotionBlockXText(plugin,
146                 this,
147                 x + title->get_w() + 10 + block_x->get_w() + 10,
148                 y + 10));
149
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,
153                 y));
154
155
156
157         int y1 = y;
158         y += 50;
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,
162                 y));
163
164         y += 40;
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,
168                 y));
169
170
171
172
173         y += 40;
174         add_subwindow(title = new BC_Title(x, y + 10, _("Block Y:")));
175         add_subwindow(block_y = new MotionBlockY(plugin,
176                 this,
177                 x + title->get_w() + 10,
178                 y));
179         add_subwindow(block_y_text = new MotionBlockYText(plugin,
180                 this,
181                 x + title->get_w() + 10 + block_y->get_w() + 10,
182                 y + 10));
183
184         y += 50;
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,
188                 y));
189
190         y += 40;
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,
194                 y));
195
196
197
198         y += 40;
199         add_subwindow(vectors = new MotionDrawVectors(plugin,
200                 this,
201                 x,
202                 y));
203
204
205         y += 40;
206         add_subwindow(track_single = new TrackSingleFrame(plugin,
207                 this,
208                 x,
209                 y));
210         add_subwindow(title = new BC_Title(x + track_single->get_w() + 20,
211                 y,
212                 _("Frame number:")));
213         add_subwindow(track_frame_number = new TrackFrameNumber(plugin,
214                 this,
215                 x + track_single->get_w() + title->get_w() + 20,
216                 y));
217
218         y += 20;
219         add_subwindow(track_previous = new TrackPreviousFrame(plugin,
220                 this,
221                 x,
222                 y));
223
224         y += 20;
225         add_subwindow(previous_same = new PreviousFrameSameBlock(plugin,
226                 this,
227                 x,
228                 y));
229
230         y += 40;
231         y1 = y;
232         add_subwindow(title = new BC_Title(x, y, _("Master layer:")));
233         add_subwindow(master_layer = new MasterLayer(plugin,
234                 this,
235                 x + title->get_w() + 10,
236                 y));
237         master_layer->create_objects();
238         y += 30;
239
240
241         add_subwindow(title = new BC_Title(x, y, _("Action:")));
242         add_subwindow(action_type = new ActionType(plugin,
243                 this,
244                 x + title->get_w() + 10,
245                 y));
246         action_type->create_objects();
247         y += 30;
248
249
250
251
252         add_subwindow(title = new BC_Title(x, y, _("Calculation:")));
253         add_subwindow(tracking_type = new TrackingType(plugin,
254                 this,
255                 x + title->get_w() + 10,
256                 y));
257         tracking_type->create_objects();
258
259
260
261         show_window();
262         flush();
263 }
264
265 void MotionWindow::update_mode()
266 {
267         global_range_w->update(plugin->config.global_range_w,
268                 MIN_RADIUS,
269                 MAX_RADIUS);
270         global_range_h->update(plugin->config.global_range_h,
271                 MIN_RADIUS,
272                 MAX_RADIUS);
273         rotation_range->update(plugin->config.rotation_range,
274                 MIN_ROTATION,
275                 MAX_ROTATION);
276         vectors->update(plugin->config.draw_vectors);
277         global->update(plugin->config.global);
278         rotate->update(plugin->config.rotate);
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292
293 GlobalRange::GlobalRange(MotionMain *plugin,
294         int x,
295         int y,
296         int *value)
297  : BC_IPot(x,
298                 y,
299                 (int64_t)*value,
300                 (int64_t)MIN_RADIUS,
301                 (int64_t)MAX_RADIUS)
302 {
303         this->plugin = plugin;
304         this->value = value;
305 }
306
307
308 int GlobalRange::handle_event()
309 {
310         *value = (int)get_value();
311         plugin->send_configure_change();
312         return 1;
313 }
314
315
316
317
318 RotationRange::RotationRange(MotionMain *plugin,
319         int x,
320         int y)
321  : BC_IPot(x,
322                 y,
323                 (int64_t)plugin->config.rotation_range,
324                 (int64_t)MIN_ROTATION,
325                 (int64_t)MAX_ROTATION)
326 {
327         this->plugin = plugin;
328 }
329
330
331 int RotationRange::handle_event()
332 {
333         plugin->config.rotation_range = (int)get_value();
334         plugin->send_configure_change();
335         return 1;
336 }
337
338
339
340
341 RotationCenter::RotationCenter(MotionMain *plugin,
342         int x,
343         int y)
344  : BC_IPot(x,
345                 y,
346                 (int64_t)plugin->config.rotation_center,
347                 (int64_t)-MAX_ROTATION,
348                 (int64_t)MAX_ROTATION)
349 {
350         this->plugin = plugin;
351 }
352
353
354 int RotationCenter::handle_event()
355 {
356         plugin->config.rotation_center = (int)get_value();
357         plugin->send_configure_change();
358         return 1;
359 }
360
361
362
363
364
365
366 BlockSize::BlockSize(MotionMain *plugin,
367         int x,
368         int y,
369         int *value)
370  : BC_IPot(x,
371                 y,
372                 (int64_t)*value,
373                 (int64_t)MIN_BLOCK,
374                 (int64_t)MAX_BLOCK)
375 {
376         this->plugin = plugin;
377         this->value = value;
378 }
379
380
381 int BlockSize::handle_event()
382 {
383         *value = (int)get_value();
384         plugin->send_configure_change();
385         return 1;
386 }
387
388
389
390
391
392
393
394
395
396
397
398
399
400 GlobalSearchPositions::GlobalSearchPositions(MotionMain *plugin,
401         int x,
402         int y,
403         int w)
404  : BC_PopupMenu(x,
405         y,
406         w,
407         "",
408         1)
409 {
410         this->plugin = plugin;
411 }
412 void GlobalSearchPositions::create_objects()
413 {
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);
430         set_text(string);
431 }
432
433 int GlobalSearchPositions::handle_event()
434 {
435         plugin->config.global_positions = atoi(get_text());
436         plugin->send_configure_change();
437         return 1;
438 }
439
440
441
442
443
444
445
446 RotationSearchPositions::RotationSearchPositions(MotionMain *plugin,
447         int x,
448         int y,
449         int w)
450  : BC_PopupMenu(x,
451         y,
452         w,
453         "",
454         1)
455 {
456         this->plugin = plugin;
457 }
458 void RotationSearchPositions::create_objects()
459 {
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);
466         set_text(string);
467 }
468
469 int RotationSearchPositions::handle_event()
470 {
471         plugin->config.rotate_positions = atoi(get_text());
472         plugin->send_configure_change();
473         return 1;
474 }
475
476
477
478
479
480
481
482
483 MotionMagnitude::MotionMagnitude(MotionMain *plugin,
484         int x,
485         int y)
486  : BC_IPot(x,
487                 y,
488                 (int64_t)plugin->config.magnitude,
489                 (int64_t)0,
490                 (int64_t)100)
491 {
492         this->plugin = plugin;
493 }
494
495 int MotionMagnitude::handle_event()
496 {
497         plugin->config.magnitude = (int)get_value();
498         plugin->send_configure_change();
499         return 1;
500 }
501
502
503 MotionReturnSpeed::MotionReturnSpeed(MotionMain *plugin,
504         int x,
505         int y)
506  : BC_IPot(x,
507                 y,
508                 (int64_t)plugin->config.return_speed,
509                 (int64_t)0,
510                 (int64_t)100)
511 {
512         this->plugin = plugin;
513 }
514
515 int MotionReturnSpeed::handle_event()
516 {
517         plugin->config.return_speed = (int)get_value();
518         plugin->send_configure_change();
519         return 1;
520 }
521
522
523
524 MotionRMagnitude::MotionRMagnitude(MotionMain *plugin,
525         int x,
526         int y)
527  : BC_IPot(x,
528                 y,
529                 (int64_t)plugin->config.rotate_magnitude,
530                 (int64_t)0,
531                 (int64_t)90)
532 {
533         this->plugin = plugin;
534 }
535
536 int MotionRMagnitude::handle_event()
537 {
538         plugin->config.rotate_magnitude = (int)get_value();
539         plugin->send_configure_change();
540         return 1;
541 }
542
543
544
545 MotionRReturnSpeed::MotionRReturnSpeed(MotionMain *plugin,
546         int x,
547         int y)
548  : BC_IPot(x,
549                 y,
550                 (int64_t)plugin->config.rotate_return_speed,
551                 (int64_t)0,
552                 (int64_t)100)
553 {
554         this->plugin = plugin;
555 }
556
557 int MotionRReturnSpeed::handle_event()
558 {
559         plugin->config.rotate_return_speed = (int)get_value();
560         plugin->send_configure_change();
561         return 1;
562 }
563
564
565
566
567
568 MotionGlobal::MotionGlobal(MotionMain *plugin,
569         MotionWindow *gui,
570         int x,
571         int y)
572  : BC_CheckBox(x,
573         y,
574         plugin->config.global,
575         _("Track translation"))
576 {
577         this->plugin = plugin;
578         this->gui = gui;
579 }
580
581 int MotionGlobal::handle_event()
582 {
583         plugin->config.global = get_value();
584         plugin->send_configure_change();
585         return 1;
586 }
587
588 MotionRotate::MotionRotate(MotionMain *plugin,
589         MotionWindow *gui,
590         int x,
591         int y)
592  : BC_CheckBox(x,
593         y,
594         plugin->config.rotate,
595         _("Track rotation"))
596 {
597         this->plugin = plugin;
598         this->gui = gui;
599 }
600
601 int MotionRotate::handle_event()
602 {
603         plugin->config.rotate = get_value();
604         plugin->send_configure_change();
605         return 1;
606 }
607
608
609
610
611
612 MotionBlockX::MotionBlockX(MotionMain *plugin,
613         MotionWindow *gui,
614         int x,
615         int y)
616  : BC_FPot(x,
617         y,
618         plugin->config.block_x,
619         (float)0,
620         (float)100)
621 {
622         this->plugin = plugin;
623         this->gui = gui;
624 }
625
626 int MotionBlockX::handle_event()
627 {
628         plugin->config.block_x = get_value();
629         gui->block_x_text->update((float)plugin->config.block_x);
630         plugin->send_configure_change();
631         return 1;
632 }
633
634
635
636
637 MotionBlockY::MotionBlockY(MotionMain *plugin,
638         MotionWindow *gui,
639         int x,
640         int y)
641  : BC_FPot(x,
642         y,
643         (float)plugin->config.block_y,
644         (float)0,
645         (float)100)
646 {
647         this->plugin = plugin;
648         this->gui = gui;
649 }
650
651 int MotionBlockY::handle_event()
652 {
653         plugin->config.block_y = get_value();
654         gui->block_y_text->update((float)plugin->config.block_y);
655         plugin->send_configure_change();
656         return 1;
657 }
658
659 MotionBlockXText::MotionBlockXText(MotionMain *plugin,
660         MotionWindow *gui,
661         int x,
662         int y)
663  : BC_TextBox(x,
664         y,
665         75,
666         1,
667         (float)plugin->config.block_x)
668 {
669         this->plugin = plugin;
670         this->gui = gui;
671         set_precision(4);
672 }
673
674 int MotionBlockXText::handle_event()
675 {
676         plugin->config.block_x = atof(get_text());
677         gui->block_x->update(plugin->config.block_x);
678         plugin->send_configure_change();
679         return 1;
680 }
681
682
683
684
685 MotionBlockYText::MotionBlockYText(MotionMain *plugin,
686         MotionWindow *gui,
687         int x,
688         int y)
689  : BC_TextBox(x,
690         y,
691         75,
692         1,
693         (float)plugin->config.block_y)
694 {
695         this->plugin = plugin;
696         this->gui = gui;
697         set_precision(4);
698 }
699
700 int MotionBlockYText::handle_event()
701 {
702         plugin->config.block_y = atof(get_text());
703         gui->block_y->update(plugin->config.block_y);
704         plugin->send_configure_change();
705         return 1;
706 }
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723 MotionDrawVectors::MotionDrawVectors(MotionMain *plugin,
724         MotionWindow *gui,
725         int x,
726         int y)
727  : BC_CheckBox(x,
728         y,
729         plugin->config.draw_vectors,
730         _("Draw vectors"))
731 {
732         this->gui = gui;
733         this->plugin = plugin;
734 }
735
736 int MotionDrawVectors::handle_event()
737 {
738         plugin->config.draw_vectors = get_value();
739         plugin->send_configure_change();
740         return 1;
741 }
742
743
744
745
746
747
748
749
750 TrackSingleFrame::TrackSingleFrame(MotionMain *plugin,
751         MotionWindow *gui,
752         int x,
753         int y)
754  : BC_Radial(x,
755         y,
756         plugin->config.tracking_object == MotionScan::TRACK_SINGLE,
757         _("Track single frame"))
758 {
759         this->plugin = plugin;
760         this->gui = gui;
761 }
762
763 int TrackSingleFrame::handle_event()
764 {
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();
770         return 1;
771 }
772
773
774
775
776
777
778
779
780 TrackFrameNumber::TrackFrameNumber(MotionMain *plugin,
781         MotionWindow *gui,
782         int x,
783         int y)
784  : BC_TextBox(x, y, 100, 1, plugin->config.track_frame)
785 {
786         this->plugin = plugin;
787         this->gui = gui;
788         if(plugin->config.tracking_object != MotionScan::TRACK_SINGLE) disable();
789 }
790
791 int TrackFrameNumber::handle_event()
792 {
793         plugin->config.track_frame = atol(get_text());
794         plugin->send_configure_change();
795         return 1;
796 }
797
798
799
800
801
802
803
804 TrackPreviousFrame::TrackPreviousFrame(MotionMain *plugin,
805         MotionWindow *gui,
806         int x,
807         int y)
808  : BC_Radial(x,
809         y,
810         plugin->config.tracking_object == MotionScan::TRACK_PREVIOUS,
811         _("Track previous frame"))
812 {
813         this->plugin = plugin;
814         this->gui = gui;
815 }
816 int TrackPreviousFrame::handle_event()
817 {
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();
823         return 1;
824 }
825
826
827
828
829
830
831
832
833 PreviousFrameSameBlock::PreviousFrameSameBlock(MotionMain *plugin,
834         MotionWindow *gui,
835         int x,
836         int y)
837  : BC_Radial(x,
838         y,
839         plugin->config.tracking_object == MotionScan::PREVIOUS_SAME_BLOCK,
840         _("Previous frame same block"))
841 {
842         this->plugin = plugin;
843         this->gui = gui;
844 }
845 int PreviousFrameSameBlock::handle_event()
846 {
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();
852         return 1;
853 }
854
855
856
857
858
859
860
861
862 MasterLayer::MasterLayer(MotionMain *plugin, MotionWindow *gui, int x, int y)
863  : BC_PopupMenu(x,
864         y,
865         calculate_w(gui),
866         to_text(plugin->config.bottom_is_master))
867 {
868         this->plugin = plugin;
869         this->gui = gui;
870 }
871
872 int MasterLayer::handle_event()
873 {
874         plugin->config.bottom_is_master = from_text(get_text());
875         plugin->send_configure_change();
876         return 1;
877 }
878
879 void MasterLayer::create_objects()
880 {
881         add_item(new BC_MenuItem(to_text(0)));
882         add_item(new BC_MenuItem(to_text(1)));
883 }
884
885 int MasterLayer::from_text(char *text)
886 {
887         if(!strcmp(text, _("Top"))) return 0;
888         return 1;
889 }
890
891 char* MasterLayer::to_text(int mode)
892 {
893         return mode ? _("Bottom") : _("Top");
894 }
895
896 int MasterLayer::calculate_w(MotionWindow *gui)
897 {
898         int result = 0;
899         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0)));
900         result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1)));
901         return result + 50;
902 }
903
904
905
906
907
908
909
910
911 ActionType::ActionType(MotionMain *plugin, MotionWindow *gui, int x, int y)
912  : BC_PopupMenu(x,
913         y,
914         calculate_w(gui),
915         to_text(plugin->config.action_type))
916 {
917         this->plugin = plugin;
918         this->gui = gui;
919 }
920
921 int ActionType::handle_event()
922 {
923         plugin->config.action_type = from_text(get_text());
924         plugin->send_configure_change();
925         return 1;
926 }
927
928 void ActionType::create_objects()
929 {
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)));
935 }
936
937 int ActionType::from_text(char *text)
938 {
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;
944 }
945
946 char* ActionType::to_text(int mode)
947 {
948         switch(mode)
949         {
950                 case MotionScan::TRACK:
951                         return _("Track Subpixel");
952                         break;
953                 case MotionScan::TRACK_PIXEL:
954                         return _("Track Pixel");
955                         break;
956                 case MotionScan::STABILIZE:
957                         return _("Stabilize Subpixel");
958                         break;
959                 case MotionScan::STABILIZE_PIXEL:
960                         return _("Stabilize Pixel");
961                         break;
962                 case MotionScan::NOTHING:
963                         return _("Do Nothing");
964                         break;
965         }
966 }
967
968 int ActionType::calculate_w(MotionWindow *gui)
969 {
970         int result = 0;
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)));
976         return result + 50;
977 }
978
979
980
981
982
983 TrackingType::TrackingType(MotionMain *plugin, MotionWindow *gui, int x, int y)
984  : BC_PopupMenu(x,
985         y,
986         calculate_w(gui),
987         to_text(plugin->config.tracking_type))
988 {
989         this->plugin = plugin;
990         this->gui = gui;
991 }
992
993 int TrackingType::handle_event()
994 {
995         plugin->config.tracking_type = from_text(get_text());
996         plugin->send_configure_change();
997         return 1;
998 }
999
1000 void TrackingType::create_objects()
1001 {
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)));
1006 }
1007
1008 int TrackingType::from_text(char *text)
1009 {
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;
1014 }
1015
1016 char* TrackingType::to_text(int mode)
1017 {
1018         switch(mode)
1019         {
1020                 case MotionScan::NO_CALCULATE:
1021                         return _("Don't Calculate");
1022                         break;
1023                 case MotionScan::CALCULATE:
1024                         return _("Recalculate");
1025                         break;
1026                 case MotionScan::SAVE:
1027                         return _("Save coords to /tmp");
1028                         break;
1029                 case MotionScan::LOAD:
1030                         return _("Load coords from /tmp");
1031                         break;
1032         }
1033 }
1034
1035 int TrackingType::calculate_w(MotionWindow *gui)
1036 {
1037         int result = 0;
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)));
1042         return result + 50;
1043 }
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054 TrackDirection::TrackDirection(MotionMain *plugin, MotionWindow *gui, int x, int y)
1055  : BC_PopupMenu(x,
1056         y,
1057         calculate_w(gui),
1058         to_text(plugin->config.horizontal_only, plugin->config.vertical_only))
1059 {
1060         this->plugin = plugin;
1061         this->gui = gui;
1062 }
1063
1064 int TrackDirection::handle_event()
1065 {
1066         from_text(&plugin->config.horizontal_only, &plugin->config.vertical_only, get_text());
1067         plugin->send_configure_change();
1068         return 1;
1069 }
1070
1071 void TrackDirection::create_objects()
1072 {
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)));
1076 }
1077
1078 void TrackDirection::from_text(int *horizontal_only, int *vertical_only, char *text)
1079 {
1080         *horizontal_only = 0;
1081         *vertical_only = 0;
1082         if(!strcmp(text, to_text(1, 0))) *horizontal_only = 1;
1083         if(!strcmp(text, to_text(0, 1))) *vertical_only = 1;
1084 }
1085
1086 char* TrackDirection::to_text(int horizontal_only, int vertical_only)
1087 {
1088         if(horizontal_only) return _("Horizontal only");
1089         if(vertical_only) return _("Vertical only");
1090         return _("Both");
1091 }
1092
1093 int TrackDirection::calculate_w(MotionWindow *gui)
1094 {
1095         int result = 0;
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)));
1099         return result + 50;
1100 }
1101