4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5 * Copyright (C) 2003-2016 Cinelerra CV contributors
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "bcdisplayinfo.h"
27 #include "edlsession.h"
29 #include "motion-cv.h"
30 #include "motionwindow-cv.h"
32 #include "pluginserver.h"
34 MotionCVWindow::MotionCVWindow(MotionCVMain *plugin)
35 : PluginClientWindow(plugin, xS(815), yS(600), xS(815), yS(600), 0)
37 this->plugin = plugin;
40 MotionCVWindow::~MotionCVWindow()
44 void MotionCVWindow::create_objects()
46 int xs10 = xS(10), xs20 = xS(20), xs30 = xS(30), xs50 = xS(50), xs120 = xS(120), xs410 = xS(410);
47 int ys10 = yS(10), ys20 = yS(20), ys30 = yS(30), ys40 = yS(40), ys50 = yS(50);
48 int x1 = xs10, x = xs10, y = ys10;
52 add_subwindow(global = new MotionCVGlobal(plugin, this, x1, y));
53 add_subwindow(rotate = new MotionCVRotate(plugin, this, x2, y));
56 add_subwindow(title = new BC_Title(x1, y,
57 _("Translation search radius:\n(W/H Percent of image)")));
58 add_subwindow(global_range_w = new GlobalRange(plugin,
59 x1 + title->get_w() + xs10, y,
60 &plugin->config.global_range_w));
61 add_subwindow(global_range_h = new GlobalRange(plugin,
62 x1 + title->get_w() + xs30 + global_range_w->get_w(), y,
63 &plugin->config.global_range_h));
65 add_subwindow(title = new BC_Title(x2, y,
66 _("Rotation search radius:\n(Degrees)")));
67 add_subwindow(rotation_range =
68 new RotationRange(plugin, x2 + title->get_w() + xs10, y));
71 add_subwindow(title = new BC_Title(x1, y,
72 _("Translation block size:\n(W/H Percent of image)")));
73 add_subwindow(global_block_w = new BlockSize(plugin,
74 x1 + title->get_w() + xs10, y,
75 &plugin->config.global_block_w));
76 add_subwindow(global_block_h = new BlockSize(plugin,
77 x1 + title->get_w() + xs30 + global_block_w->get_w(), y,
78 &plugin->config.global_block_h));
80 add_subwindow(title = new BC_Title(x2, y,
81 _("Rotation block size:\n(W/H Percent of image)")));
82 add_subwindow(rotation_block_w = new BlockSize(plugin,
83 x2 + title->get_w() + xs10, y,
84 &plugin->config.rotation_block_w));
85 add_subwindow(rotation_block_h = new BlockSize(plugin,
86 x2 + title->get_w() + xs30 + rotation_block_w->get_w(), y,
87 &plugin->config.rotation_block_h));
90 add_subwindow(title = new BC_Title(x1, y, _("Translation search steps:")));
91 add_subwindow(global_search_positions = new GlobalSearchPositions(plugin,
92 x1 + title->get_w() + xs10, y, xs120));
93 global_search_positions->create_objects();
95 add_subwindow(title = new BC_Title(x2, y, _("Rotation search steps:")));
96 add_subwindow(rotation_search_positions = new RotationSearchPositions(plugin,
97 x2 + title->get_w() + xs10, y, xs120));
98 rotation_search_positions->create_objects();
101 add_subwindow(title = new BC_Title(x, y, _("Translation direction:")));
102 add_subwindow(mode3 = new Mode3(plugin,
103 this, x + title->get_w() + xs10, y));
104 mode3->create_objects();
106 y += ys40; int y1 = y;
107 add_subwindow(title = new BC_Title(x2, y, _("Tracking file:")));
108 add_subwindow(tracking_file = new MotionCVTrackingFile(plugin,
109 plugin->config. tracking_file, this,
110 x2 + title->get_w() + xs20, y));
111 y1 += tracking_file->get_h() + ys10;
113 add_subwindow(title = new BC_Title(x, y + xs10, _("Block X:")));
114 add_subwindow(block_x = new MotionCVBlockX(plugin, this,
115 x + title->get_w() + xs10, y));
116 add_subwindow(block_x_text = new MotionCVBlockXText(plugin,
117 this, x + title->get_w() + xs10 + block_x->get_w() + xs10, y + ys10));
120 add_subwindow(title = new BC_Title(x, y + ys10, _("Block Y:")));
121 add_subwindow(block_y = new MotionCVBlockY(plugin, this,
122 x + title->get_w() + xs10, y));
123 add_subwindow(block_y_text = new MotionCVBlockYText(plugin, this,
124 x + title->get_w() + xs10 + block_y->get_w() + xs10, y + ys10));
126 add_subwindow(title = new BC_Title(x2, y1 + ys10, _("Maximum absolute offset:")));
127 add_subwindow(magnitude = new MotionCVMagnitude(plugin,
128 x2 + title->get_w() + xs10, y1));
131 add_subwindow(title = new BC_Title(x2, y1 + ys10, _("Settling speed:")));
132 add_subwindow(return_speed = new MotionCVReturnSpeed(plugin,
133 x2 + title->get_w() + xs10, y1));
136 add_subwindow(vectors = new MotionCVDrawVectors(plugin, this, x2, y1));
137 y = y1 + vectors->get_h() + ys10;
140 add_subwindow(track_single =
141 new TrackSingleFrame(plugin, this, x1, y1));
143 add_subwindow(track_previous = new TrackPreviousFrame(plugin, this, x, y));
145 add_subwindow(previous_same = new PreviousFrameSameBlock(plugin, this, x, y));
148 add_subwindow(title = new BC_Title(x, y, _("Master layer:")));
149 add_subwindow(master_layer = new MasterLayer(plugin, this,
150 x + title->get_w() + xs10, y));
151 master_layer->create_objects();
152 add_subwindow(title =
153 new BC_Title(x1=x2, y1=y, _("Frame number:")));
154 add_subwindow(track_frame_number =
155 new TrackFrameNumber(plugin, this, x1 += title->get_w(), y1));
156 if( plugin->config.mode3 != MotionCVConfig::TRACK_SINGLE )
157 track_frame_number->disable();
159 add_subwindow(addtrackedframeoffset =
160 new AddTrackedFrameOffset(plugin, this, x1=x2, y1+=track_frame_number->get_h()));
161 int pef = client->server->mwindow->edl->session->video_every_frame;
162 add_subwindow(pef_title = new BC_Title(x1=x2+xs50, y1+=addtrackedframeoffset->get_h() + yS(5),
163 !pef ? _("For best results\n"
164 " Set: Play every frame\n"
165 " Preferences-> Playback-> Video Out") :
166 _("Currently using: Play every frame"), MEDIUMFONT,
167 !pef ? RED : GREEN));
170 add_subwindow(title = new BC_Title(x, y, _("Action:")));
171 add_subwindow(mode1 = new Mode1(plugin, this,
172 x + title->get_w() + xs10, y));
173 mode1->create_objects();
176 add_subwindow(title = new BC_Title(x, y, _("Calculation:")));
177 add_subwindow(mode2 = new Mode2(plugin, this,
178 x + title->get_w() + xs10, y));
179 mode2->create_objects();
184 void MotionCVWindow::update_mode()
186 global_range_w->update(plugin->config.global_range_w, MIN_RADIUS, MAX_RADIUS);
187 global_range_h->update(plugin->config.global_range_h, MIN_RADIUS, MAX_RADIUS);
188 rotation_range->update(plugin->config.rotation_range, MIN_ROTATION, MAX_ROTATION);
189 vectors->update(plugin->config.draw_vectors);
190 tracking_file->update(plugin->config.tracking_file);
191 global->update(plugin->config.global);
192 rotate->update(plugin->config.rotate);
193 addtrackedframeoffset->update(plugin->config.addtrackedframeoffset);
196 GlobalRange::GlobalRange(MotionCVMain *plugin, int x, int y, int *value)
197 :BC_IPot(x, y, (int64_t) * value, (int64_t) MIN_RADIUS, (int64_t) MAX_RADIUS)
199 this->plugin = plugin;
203 int GlobalRange::handle_event()
205 *value = (int)get_value();
206 plugin->send_configure_change();
210 RotationRange::RotationRange(MotionCVMain *plugin, int x, int y)
213 y, (int64_t) plugin->config.rotation_range,
214 (int64_t) MIN_ROTATION, (int64_t) MAX_ROTATION)
216 this->plugin = plugin;
219 int RotationRange::handle_event()
221 plugin->config.rotation_range = (int)get_value();
222 plugin->send_configure_change();
226 BlockSize::BlockSize(MotionCVMain *plugin, int x, int y, int *value)
227 : BC_IPot(x, y, (int64_t) * value, (int64_t) MIN_BLOCK, (int64_t) MAX_BLOCK)
229 this->plugin = plugin;
233 int BlockSize::handle_event()
235 *value = (int)get_value();
236 plugin->send_configure_change();
240 GlobalSearchPositions::GlobalSearchPositions(MotionCVMain *plugin,
242 : BC_PopupMenu(x, y, w, "", 1)
244 this->plugin = plugin;
247 void GlobalSearchPositions::create_objects()
249 add_item(new BC_MenuItem("64"));
250 add_item(new BC_MenuItem("128"));
251 add_item(new BC_MenuItem("256"));
252 add_item(new BC_MenuItem("512"));
253 add_item(new BC_MenuItem("1024"));
254 add_item(new BC_MenuItem("2048"));
255 add_item(new BC_MenuItem("4096"));
256 add_item(new BC_MenuItem("8192"));
257 add_item(new BC_MenuItem("16384"));
258 add_item(new BC_MenuItem("32768"));
259 add_item(new BC_MenuItem("65536"));
260 add_item(new BC_MenuItem("131072"));
261 char string[BCTEXTLEN];
262 sprintf(string, "%d", plugin->config.global_positions);
266 int GlobalSearchPositions::handle_event()
268 plugin->config.global_positions = atoi(get_text());
269 plugin->send_configure_change();
273 RotationSearchPositions::RotationSearchPositions(MotionCVMain *plugin,
275 : BC_PopupMenu(x, y, w, "", 1)
277 this->plugin = plugin;
280 void RotationSearchPositions::create_objects()
282 add_item(new BC_MenuItem("4"));
283 add_item(new BC_MenuItem("8"));
284 add_item(new BC_MenuItem("16"));
285 add_item(new BC_MenuItem("32"));
286 char string[BCTEXTLEN];
287 sprintf(string, "%d", plugin->config.rotate_positions);
291 int RotationSearchPositions::handle_event()
293 plugin->config.rotate_positions = atoi(get_text());
294 plugin->send_configure_change();
298 MotionCVMagnitude::MotionCVMagnitude(MotionCVMain *plugin, int x, int y)
299 : BC_IPot(x, y, (int64_t) plugin->config.magnitude, (int64_t) 0, (int64_t) 100)
301 this->plugin = plugin;
304 int MotionCVMagnitude::handle_event()
306 plugin->config.magnitude = (int)get_value();
307 plugin->send_configure_change();
311 MotionCVReturnSpeed::MotionCVReturnSpeed(MotionCVMain *plugin, int x, int y)
312 : BC_IPot(x, y, (int64_t) plugin->config.return_speed, (int64_t) 0, (int64_t) 100)
314 this->plugin = plugin;
317 int MotionCVReturnSpeed::handle_event()
319 plugin->config.return_speed = (int)get_value();
320 plugin->send_configure_change();
324 AddTrackedFrameOffset::AddTrackedFrameOffset(MotionCVMain *plugin,
325 MotionCVWindow *gui, int x, int y)
326 : BC_CheckBox(x, y, plugin->config.addtrackedframeoffset,
327 _("Add (loaded) offset from tracked frame"))
329 this->plugin = plugin;
333 int AddTrackedFrameOffset::handle_event()
335 plugin->config.addtrackedframeoffset = get_value();
336 plugin->send_configure_change();
340 MotionCVTrackingFile::MotionCVTrackingFile(MotionCVMain *plugin,
341 const char *filename, MotionCVWindow *gui, int x, int y)
342 : BC_TextBox(x, y, xS(250), 1, filename)
344 this->plugin = plugin;
348 int MotionCVTrackingFile::handle_event()
350 strcpy(plugin->config.tracking_file, get_text());
351 plugin->send_configure_change();
355 MotionCVGlobal::MotionCVGlobal(MotionCVMain *plugin,
356 MotionCVWindow *gui, int x, int y)
357 :BC_CheckBox(x, y, plugin->config.global, _("Track translation"))
359 this->plugin = plugin;
363 int MotionCVGlobal::handle_event()
365 plugin->config.global = get_value();
366 plugin->send_configure_change();
370 MotionCVRotate::MotionCVRotate(MotionCVMain *plugin,
371 MotionCVWindow *gui, int x, int y)
372 : BC_CheckBox(x, y, plugin->config.rotate, _("Track rotation"))
374 this->plugin = plugin;
378 int MotionCVRotate::handle_event()
380 plugin->config.rotate = get_value();
381 plugin->send_configure_change();
385 MotionCVBlockX::MotionCVBlockX(MotionCVMain *plugin,
386 MotionCVWindow *gui, int x, int y)
387 : BC_FPot(x, y, plugin->config.block_x, (float)0, (float)100)
389 this->plugin = plugin;
393 int MotionCVBlockX::handle_event()
395 plugin->config.block_x = get_value();
396 gui->block_x_text->update((float)plugin->config.block_x);
397 plugin->send_configure_change();
401 MotionCVBlockY::MotionCVBlockY(MotionCVMain *plugin,
402 MotionCVWindow *gui, int x, int y)
403 : BC_FPot(x, y, (float)plugin->config.block_y, (float)0, (float)100)
405 this->plugin = plugin;
409 int MotionCVBlockY::handle_event()
411 plugin->config.block_y = get_value();
412 gui->block_y_text->update((float)plugin->config.block_y);
413 plugin->send_configure_change();
417 MotionCVBlockXText::MotionCVBlockXText(MotionCVMain *plugin,
418 MotionCVWindow *gui, int x, int y)
419 : BC_TextBox(x, y, xS(75), 1, (float)plugin->config.block_x)
421 this->plugin = plugin;
426 int MotionCVBlockXText::handle_event()
428 plugin->config.block_x = atof(get_text());
429 gui->block_x->update(plugin->config.block_x);
430 plugin->send_configure_change();
434 MotionCVBlockYText::MotionCVBlockYText(MotionCVMain *plugin,
435 MotionCVWindow *gui, int x, int y)
436 : BC_TextBox(x, y, xS(75), 1, (float)plugin->config.block_y)
438 this->plugin = plugin;
443 int MotionCVBlockYText::handle_event()
445 plugin->config.block_y = atof(get_text());
446 gui->block_y->update(plugin->config.block_y);
447 plugin->send_configure_change();
451 MotionCVDrawVectors::MotionCVDrawVectors(MotionCVMain *plugin,
452 MotionCVWindow *gui, int x, int y)
453 : BC_CheckBox(x, y, plugin->config.draw_vectors, _("Draw vectors"))
456 this->plugin = plugin;
459 int MotionCVDrawVectors::handle_event()
461 plugin->config.draw_vectors = get_value();
462 plugin->send_configure_change();
466 TrackSingleFrame::TrackSingleFrame(MotionCVMain *plugin,
467 MotionCVWindow *gui, int x, int y)
470 y, plugin->config.mode3 == MotionCVConfig::TRACK_SINGLE,
471 _("Track single frame"))
473 this->plugin = plugin;
477 int TrackSingleFrame::handle_event()
479 plugin->config.mode3 = MotionCVConfig::TRACK_SINGLE;
480 gui->track_previous->update(0);
481 gui->previous_same->update(0);
482 gui->track_frame_number->enable();
483 plugin->send_configure_change();
487 TrackFrameNumber::TrackFrameNumber(MotionCVMain *plugin,
488 MotionCVWindow *gui, int x, int y)
489 : BC_TextBox(x, y, xS(100), 1, plugin->config.track_frame)
491 this->plugin = plugin;
495 int TrackFrameNumber::handle_event()
497 plugin->config.track_frame = atol(get_text());
498 plugin->send_configure_change();
502 TrackPreviousFrame::TrackPreviousFrame(MotionCVMain *plugin,
503 MotionCVWindow *gui, int x, int y)
506 y, plugin->config.mode3 == MotionCVConfig::TRACK_PREVIOUS,
507 _("Track previous frame"))
509 this->plugin = plugin;
513 int TrackPreviousFrame::handle_event()
515 plugin->config.mode3 = MotionCVConfig::TRACK_PREVIOUS;
516 gui->track_single->update(0);
517 gui->previous_same->update(0);
518 gui->track_frame_number->disable();
519 plugin->send_configure_change();
523 PreviousFrameSameBlock::PreviousFrameSameBlock(MotionCVMain *plugin,
524 MotionCVWindow *gui, int x, int y)
527 y, plugin->config.mode3 == MotionCVConfig::PREVIOUS_SAME_BLOCK,
528 _("Previous frame same block"))
530 this->plugin = plugin;
534 int PreviousFrameSameBlock::handle_event()
536 plugin->config.mode3 = MotionCVConfig::PREVIOUS_SAME_BLOCK;
537 gui->track_single->update(0);
538 gui->track_previous->update(0);
539 gui->track_frame_number->disable();
540 plugin->send_configure_change();
544 MasterLayer::MasterLayer(MotionCVMain *plugin, MotionCVWindow *gui, int x,
546 : BC_PopupMenu(x, y, calculate_w(gui),
547 to_text(plugin->config.bottom_is_master))
549 this->plugin = plugin;
553 int MasterLayer::handle_event()
555 plugin->config.bottom_is_master = from_text(get_text());
556 plugin->send_configure_change();
560 void MasterLayer::create_objects()
562 add_item(new BC_MenuItem(to_text(0)));
563 add_item(new BC_MenuItem(to_text(1)));
566 int MasterLayer::from_text(char *text)
568 if( !strcmp(text, _("Top")) ) return 0;
572 const char *MasterLayer::to_text(int mode)
574 return mode ? _("Bottom") : _("Top");
577 int MasterLayer::calculate_w(MotionCVWindow *gui)
580 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0)));
581 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1)));
582 return result + xS(80);
585 Mode1::Mode1(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
586 : BC_PopupMenu(x, y, calculate_w(gui), to_text(plugin->config.mode1))
588 this->plugin = plugin;
592 int Mode1::handle_event()
594 plugin->config.mode1 = from_text(get_text());
595 plugin->send_configure_change();
599 void Mode1::create_objects()
601 add_item(new BC_MenuItem(to_text(MotionCVConfig::TRACK)));
602 add_item(new BC_MenuItem(to_text(MotionCVConfig::TRACK_PIXEL)));
603 add_item(new BC_MenuItem(to_text(MotionCVConfig::STABILIZE)));
604 add_item(new BC_MenuItem(to_text(MotionCVConfig::STABILIZE_PIXEL)));
605 add_item(new BC_MenuItem(to_text(MotionCVConfig::NOTHING)));
608 int Mode1::from_text(char *text)
610 if( !strcmp(text, _("Track Subpixel")) ) return MotionCVConfig::TRACK;
611 if( !strcmp(text, _("Track Pixel")) ) return MotionCVConfig::TRACK_PIXEL;
612 if( !strcmp(text, _("Stabilize Subpixel")) ) return MotionCVConfig::STABILIZE;
613 if( !strcmp(text, _("Stabilize Pixel")) ) return MotionCVConfig::STABILIZE_PIXEL;
614 //if( !strcmp(text, _("Do Nothing")) ) return MotionCVConfig::NOTHING;
615 return MotionCVConfig::NOTHING;
618 const char *Mode1::to_text(int mode)
621 case MotionCVConfig::TRACK: return _("Track Subpixel");
622 case MotionCVConfig::TRACK_PIXEL: return _("Track Pixel");
623 case MotionCVConfig::STABILIZE: return _("Stabilize Subpixel");
624 case MotionCVConfig::STABILIZE_PIXEL: return _("Stabilize Pixel");
625 case MotionCVConfig::NOTHING: return _("Do Nothing");
630 int Mode1::calculate_w(MotionCVWindow *gui)
633 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::TRACK)));
634 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::TRACK_PIXEL)));
635 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::STABILIZE)));
636 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::STABILIZE_PIXEL)));
637 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::NOTHING)));
638 return result + xS(80);
641 Mode2::Mode2(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
642 : BC_PopupMenu(x, y, calculate_w(gui), to_text(plugin->config.mode2))
644 this->plugin = plugin;
648 int Mode2::handle_event()
650 plugin->config.mode2 = from_text(get_text());
651 plugin->send_configure_change();
655 void Mode2::create_objects()
657 add_item(new BC_MenuItem(to_text(MotionCVConfig::SAVE)));
658 add_item(new BC_MenuItem(to_text(MotionCVConfig::LOAD)));
659 add_item(new BC_MenuItem(to_text(MotionCVConfig::RECALCULATE)));
660 add_item(new BC_MenuItem(to_text(MotionCVConfig::NO_CALCULATE)));
663 int Mode2::from_text(char *text)
665 if( !strcmp(text, _("Recalculate")) ) return MotionCVConfig::RECALCULATE;
666 if( !strcmp(text, _("Save coords to tracking file")) ) return MotionCVConfig::SAVE;
667 if( !strcmp(text, _("Load coords from tracking file")) ) return MotionCVConfig::LOAD;
668 //if( !strcmp(text, _("Don't Calculate")) ) return MotionCVConfig::NO_CALCULATE;
669 return MotionCVConfig::NO_CALCULATE;
672 const char *Mode2::to_text(int mode)
675 case MotionCVConfig::NO_CALCULATE: return _("Don't Calculate");
676 case MotionCVConfig::RECALCULATE: return _("Recalculate");
677 case MotionCVConfig::SAVE: return _("Save coords to tracking file");
678 case MotionCVConfig::LOAD: return _("Load coords from tracking file");
683 int Mode2::calculate_w(MotionCVWindow *gui)
686 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::NO_CALCULATE)));
687 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::RECALCULATE)));
688 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::SAVE)));
689 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(MotionCVConfig::LOAD)));
690 return result + xS(80);
693 Mode3::Mode3(MotionCVMain *plugin, MotionCVWindow *gui, int x, int y)
695 BC_PopupMenu(x, y, calculate_w(gui),
696 to_text(plugin->config.horizontal_only, plugin->config.vertical_only))
698 this->plugin = plugin;
702 int Mode3::handle_event()
704 from_text(&plugin->config.horizontal_only,
705 &plugin->config.vertical_only, get_text());
706 plugin->send_configure_change();
710 void Mode3::create_objects()
712 add_item(new BC_MenuItem(to_text(1, 0)));
713 add_item(new BC_MenuItem(to_text(0, 1)));
714 add_item(new BC_MenuItem(to_text(0, 0)));
717 void Mode3::from_text(int *horizontal_only, int *vertical_only, char *text)
719 *horizontal_only = 0;
721 if( !strcmp(text, to_text(1, 0)) ) *horizontal_only = 1;
722 if( !strcmp(text, to_text(0, 1)) ) *vertical_only = 1;
725 const char *Mode3::to_text(int horizontal_only, int vertical_only)
727 if( horizontal_only ) return _("Horizontal only");
728 if( vertical_only ) return _("Vertical only");
732 int Mode3::calculate_w(MotionCVWindow *gui)
735 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(1, 0)));
736 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 1)));
737 result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(0, 0)));
738 return result + xS(80);