bsd lang segv fix, enable bsd lv2, lv2 gui enable fix, proxy/ffmpeg toggle resize...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / setformat.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2012 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 "clip.h"
23 #include "cwindow.h"
24 #include "cwindowgui.h"
25 #include "datatype.h"
26 #include "bchash.h"
27 #include "edl.h"
28 #include "edlsession.h"
29 #include "formatpresets.h"
30 #include "language.h"
31 #include "levelwindow.h"
32 #include "levelwindowgui.h"
33 #include "mainerror.h"
34 #include "mainundo.h"
35 #include "mutex.h"
36 #include "mwindow.h"
37 #include "mwindowgui.h"
38 #include "new.h"
39 #include "preferences.h"
40 #include "rotateframe.h"
41 #include "setformat.h"
42 #include "theme.h"
43 #include "vframe.h"
44 #include "vwindow.h"
45 #include "vwindowgui.h"
46
47
48
49 SetFormat::SetFormat(MWindow *mwindow)
50  : BC_MenuItem(_("Format..."), _("Shift-F"), 'F')
51 {
52         set_shift(1);
53         this->mwindow = mwindow;
54         thread = new SetFormatThread(mwindow);
55 }
56
57 SetFormat::~SetFormat()
58 {
59         delete thread;
60 }
61
62 int SetFormat::handle_event()
63 {
64         if(!thread->running())
65         {
66                 thread->start();
67         }
68         else
69         {
70 // window_lock has to be locked but window can't be locked until after
71 // it is known to exist, so we neglect window_lock for now
72                 if(thread->window)
73                 {
74                         thread->window_lock->lock("SetFormat::handle_event");
75                         thread->window->lock_window("SetFormat::handle_event");
76                         thread->window->raise_window();
77                         thread->window->unlock_window();
78                         thread->window_lock->unlock();
79                 }
80         }
81         return 1;
82 }
83
84 SetFormatThread::SetFormatThread(MWindow *mwindow)
85  : Thread(1, 0, 0)
86 {
87         this->mwindow = mwindow;
88         window_lock = new Mutex("SetFormatThread::window_lock");
89         window = 0;
90 }
91
92 SetFormatThread::~SetFormatThread()
93 {
94         if( running() ) {
95                 window->set_done(1);
96                 cancel();
97         }
98         join();
99         delete window_lock;
100 }
101
102 void SetFormatThread::run()
103 {
104         orig_dimension[0] = dimension[0] = mwindow->edl->session->output_w;
105         orig_dimension[1] = dimension[1] = mwindow->edl->session->output_h;
106         auto_aspect = mwindow->defaults->get("AUTOASPECT", 0);
107         constrain_ratio = 0;
108         ratio[0] = ratio[1] = 1;
109
110         new_settings = new EDL;
111         new_settings->create_objects();
112         new_settings->copy_session(mwindow->edl);
113
114 // This locks mwindow, so it must be done outside window_lock
115         int x = mwindow->gui->get_abs_cursor_x(1) - mwindow->theme->setformat_w / 2;
116         int y = mwindow->gui->get_abs_cursor_y(1) - mwindow->theme->setformat_h / 2;
117
118         window_lock->lock("SetFormatThread::run 1");
119         window = new SetFormatWindow(mwindow, this, x, y);
120         window->create_objects();
121         window_lock->unlock();
122
123         int result = window->run_window();
124
125
126         window_lock->lock("SetFormatThread::run 2");
127         delete window;
128         window = 0;
129         window_lock->unlock();
130
131
132         if(!result)
133         {
134                 apply_changes();
135         }
136
137         mwindow->defaults->update("AUTOASPECT", auto_aspect);
138         new_settings->Garbage::remove_user();
139 }
140
141 void SetFormatThread::apply_changes()
142 {
143         double new_samplerate = new_settings->session->sample_rate;
144         double old_samplerate = mwindow->edl->session->sample_rate;
145         double new_framerate = new_settings->session->frame_rate;
146         double old_framerate = mwindow->edl->session->frame_rate;
147         int new_channels = new_settings->session->audio_channels;
148         CLAMP(new_channels, 1, MAXCHANNELS);
149
150
151
152         mwindow->undo->update_undo_before();
153
154         memcpy(&mwindow->preferences->channel_positions[new_channels - 1],
155                 new_settings->session->achannel_positions,
156                 sizeof(mwindow->preferences->channel_positions[new_channels - 1]));
157
158
159         mwindow->edl->copy_session(new_settings, 1);
160         mwindow->edl->session->output_w = dimension[0];
161         mwindow->edl->session->output_h = dimension[1];
162         mwindow->edl->retrack();
163         mwindow->edl->rechannel();
164         mwindow->edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
165         mwindow->edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
166         mwindow->save_backup();
167         mwindow->undo->update_undo_after(_("set format"), LOAD_ALL);
168
169         mwindow->resync_guis();
170 }
171
172 void SetFormatThread::update()
173 {
174         window->sample_rate->update(new_settings->session->sample_rate);
175         window->channels->update((int64_t)new_settings->session->audio_channels);
176         window->frame_rate->update((float)new_settings->session->frame_rate);
177
178         auto_aspect = 0;
179         window->auto_aspect->update(0);
180
181         constrain_ratio = 0;
182         dimension[0] = new_settings->session->output_w;
183         window->dimension[0]->update((int64_t)dimension[0]);
184         dimension[1] = new_settings->session->output_h;
185         window->dimension[1]->update((int64_t)dimension[1]);
186
187         ratio[0] = (float)dimension[0] / orig_dimension[0];
188         window->ratio[0]->update(ratio[0]);
189         ratio[1] = (float)dimension[1] / orig_dimension[1];
190         window->ratio[1]->update(ratio[1]);
191
192         window->aspect_w->update(new_settings->session->aspect_w);
193         window->aspect_h->update(new_settings->session->aspect_h);
194         window->interlace_pulldown->update(new_settings->session->interlace_mode);
195         window->color_model->update_value(new_settings->session->color_model);
196
197         window->canvas->draw();
198 }
199
200 void SetFormatThread::update_window()
201 {
202         int i, result, modified_item = 0, dimension_modified = 0, ratio_modified = 0;
203
204         for(i = 0, result = 0; i < 2 && !result; i++)
205         {
206                 if(dimension[i] < 0)
207                 {
208                         dimension[i] *= -1;
209                         result = 1;
210                         modified_item = i;
211                         dimension_modified = 1;
212                 }
213                 if(ratio[i] < 0)
214                 {
215                         ratio[i] *= -1;
216                         result = 1;
217                         modified_item = i;
218                         ratio_modified = 1;
219                 }
220         }
221
222         if(result)
223         {
224                 if(dimension_modified)
225                         ratio[modified_item] = (float)dimension[modified_item] / orig_dimension[modified_item];
226
227                 if(ratio_modified && !constrain_ratio)
228                 {
229                         dimension[modified_item] = (int)(orig_dimension[modified_item] * ratio[modified_item]);
230                         window->dimension[modified_item]->update((int64_t)dimension[modified_item]);
231                 }
232
233                 for(i = 0; i < 2; i++)
234                 {
235                         if(dimension_modified ||
236                                 (i != modified_item && ratio_modified))
237                         {
238                                 if(constrain_ratio) ratio[i] = ratio[modified_item];
239                                 window->ratio[i]->update(ratio[i]);
240                         }
241
242                         if(ratio_modified ||
243                                 (i != modified_item && dimension_modified))
244                         {
245                                 if(constrain_ratio)
246                                 {
247                                         dimension[i] = (int)(orig_dimension[i] * ratio[modified_item]);
248                                         window->dimension[i]->update((int64_t)dimension[i]);
249                                 }
250                         }
251                 }
252         }
253
254         update_aspect();
255 }
256
257 void SetFormatThread::update_aspect()
258 {
259         if(auto_aspect)
260         {
261                 char string[BCTEXTLEN];
262                 MWindow::create_aspect_ratio(new_settings->session->aspect_w,
263                         new_settings->session->aspect_h,
264                         dimension[0],
265                         dimension[1]);
266                 sprintf(string, "%.02f", new_settings->session->aspect_w);
267                 window->aspect_w->update(string);
268                 sprintf(string, "%.02f", new_settings->session->aspect_h);
269                 window->aspect_h->update(string);
270         }
271 }
272
273
274
275
276
277
278
279
280
281 SetFormatWindow::SetFormatWindow(MWindow *mwindow,
282         SetFormatThread *thread, int x, int y)
283  : BC_Window(_(PROGRAM_NAME ": Set Format"), x, y,
284         mwindow->theme->setformat_w, mwindow->theme->setformat_h,
285         -1, -1, 0, 0, 1)
286 {
287         this->mwindow = mwindow;
288         this->thread = thread;
289         presets = 0;
290 }
291 SetFormatWindow::~SetFormatWindow()
292 {
293         delete presets;
294 }
295
296 void SetFormatWindow::create_objects()
297 {
298         int x = 10, y = mwindow->theme->setformat_y1;
299         BC_TextBox *textbox;
300         BC_Title *title;
301
302         lock_window("SetFormatWindow::create_objects");
303         mwindow->theme->draw_setformat_bg(this);
304
305
306
307         presets = new SetFormatPresets(mwindow, this, x, y);
308         presets->create_objects();
309         x = presets->x; //  y = presets->y;
310         y = mwindow->theme->setformat_y2;
311
312         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, y,
313                 _("Audio"), LARGEFONT));
314         y = mwindow->theme->setformat_y3;
315
316         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, y,
317                 _("Samplerate:")));
318         add_subwindow(sample_rate = new SetSampleRateTextBox(thread,
319                 mwindow->theme->setformat_x2,
320                 y));
321         add_subwindow(new SampleRatePulldown(mwindow, sample_rate,
322                 mwindow->theme->setformat_x2 + sample_rate->get_w(), y));
323
324         y += mwindow->theme->setformat_margin;
325         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, y,
326                 _("Channels:")));
327         add_subwindow(channels = new SetChannelsTextBox(thread,
328                 mwindow->theme->setformat_x2, y));
329         add_subwindow(new BC_ITumbler(channels, 1, MAXCHANNELS,
330                 mwindow->theme->setformat_x2 + channels->get_w(), y));
331
332         y += mwindow->theme->setformat_margin;
333         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, y,
334                 _("Channel positions:")));
335         y += mwindow->theme->setformat_margin;
336         add_subwindow(new SetChannelsReset(thread,
337                 mwindow->theme->setformat_x1, y,
338                 _("Reset")));
339         add_subwindow(canvas = new SetChannelsCanvas(mwindow,
340                 thread,
341                 mwindow->theme->setformat_channels_x,
342                 mwindow->theme->setformat_channels_y,
343                 mwindow->theme->setformat_channels_w,
344                 mwindow->theme->setformat_channels_h));
345         canvas->draw();
346
347
348
349         y = mwindow->theme->setformat_y2;
350         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
351                 y,
352                 _("Video"),
353                 LARGEFONT));
354
355         y = mwindow->theme->setformat_y3;
356         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
357                 y,
358                 _("Frame rate:")));
359         add_subwindow(frame_rate = new SetFrameRateTextBox(thread,
360                 mwindow->theme->setformat_x4,
361                 y));
362         add_subwindow(new FrameRatePulldown(mwindow,
363                 frame_rate,
364                 mwindow->theme->setformat_x4 + frame_rate->get_w(),
365                 y));
366
367         y += mwindow->theme->setformat_margin;
368         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
369                 y,
370                 _("Canvas size:")));
371
372         y += mwindow->theme->setformat_margin;
373         add_subwindow(title = new BC_Title(mwindow->theme->setformat_x3, y, _("Width:")));
374         add_subwindow(dimension[0] = new ScaleSizeText(mwindow->theme->setformat_x4,
375                 y,
376                 thread,
377                 &(thread->dimension[0])));
378
379         y += mwindow->theme->setformat_margin;
380         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, y, _("Height:")));
381         add_subwindow(dimension[1] = new ScaleSizeText(mwindow->theme->setformat_x4,
382                 y,
383                 thread,
384                 &(thread->dimension[1])));
385
386         x = mwindow->theme->setformat_x4 + dimension[0]->get_w();
387         FrameSizePulldown *pulldown;
388         add_subwindow(pulldown = new FrameSizePulldown(mwindow->theme,
389                 dimension[0],
390                 dimension[1],
391                 x,
392                 y - mwindow->theme->setformat_margin));
393
394         add_subwindow(new FormatSwapExtents(mwindow,
395                 thread,
396                 this,
397                 x + pulldown->get_w() + 5,
398                 y - mwindow->theme->setformat_margin));
399
400         y += mwindow->theme->setformat_margin;
401         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
402                 y,
403                 _("W Ratio:")));
404         add_subwindow(ratio[0] = new ScaleRatioText(mwindow->theme->setformat_x4,
405                 y,
406                 thread,
407                 &(thread->ratio[0])));
408
409         y += mwindow->theme->setformat_margin;
410         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
411                 y,
412                 _("H Ratio:")));
413         add_subwindow(ratio[1] = new ScaleRatioText(mwindow->theme->setformat_x4,
414                 y,
415                 thread,
416                 &(thread->ratio[1])));
417
418         y += mwindow->theme->setformat_margin;
419         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
420                 y,
421                 _("Color model:")));
422         x = mwindow->theme->setformat_x4;
423         add_subwindow(textbox = new BC_TextBox(x,
424                 y,
425                 100,
426                 1,
427                 ""));
428         x += textbox->get_w();
429         add_subwindow(color_model = new ColormodelPulldown(mwindow,
430                 textbox,
431                 &thread->new_settings->session->color_model,
432                 x,
433                 y));
434
435         y += mwindow->theme->setformat_margin;
436         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
437                 y,
438                 _("Aspect ratio:")));
439         y += mwindow->theme->setformat_margin;
440         x = mwindow->theme->setformat_x3;
441         add_subwindow(aspect_w = new ScaleAspectText(x,
442                 y,
443                 thread,
444                 &(thread->new_settings->session->aspect_w)));
445         x += aspect_w->get_w() + 5;
446         add_subwindow(new BC_Title(x, y, ":"));
447         x += 10;
448         add_subwindow(aspect_h = new ScaleAspectText(x,
449                 y,
450                 thread,
451                 &(thread->new_settings->session->aspect_h)));
452         x += aspect_h->get_w();
453         add_subwindow(new AspectPulldown(mwindow,
454                 aspect_w,
455                 aspect_h,
456                 x,
457                 y));
458         x += 30;
459         add_subwindow(auto_aspect = new ScaleAspectAuto(x, y, thread));
460         y += mwindow->theme->setformat_margin;
461
462         // --------------------
463         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
464                 y,
465                 _("Interlace mode:")));
466         add_subwindow(textbox = new BC_TextBox(mwindow->theme->setformat_x4,
467                 y,
468                 140,
469                 1,
470                 ""));
471         add_subwindow(interlace_pulldown = new InterlacemodePulldown(mwindow,
472                 textbox,
473                 &(thread->new_settings->session->interlace_mode),
474                 (ArrayList<BC_ListBoxItem*>*)&mwindow->interlace_project_modes,
475                 mwindow->theme->setformat_x4 + textbox->get_w(),
476                 y));
477         y += mwindow->theme->setformat_margin;
478
479
480         BC_OKTextButton *ok;
481         BC_CancelTextButton *cancel;
482         add_subwindow(ok = new BC_OKTextButton(this));
483         add_subwindow(cancel = new BC_CancelTextButton(this));
484         add_subwindow(new SetFormatApply((ok->get_x() + cancel->get_x()) / 2,
485                 ok->get_y(),
486                 thread));
487         flash();
488         show_window();
489         unlock_window();
490 }
491
492 const char* SetFormatWindow::get_preset_text()
493 {
494         return "";
495 }
496
497
498 SetFormatPresets::SetFormatPresets(MWindow *mwindow,
499         SetFormatWindow *gui,
500         int x,
501         int y)
502  : FormatPresets(mwindow, 0, gui, x, y)
503 {
504
505 }
506
507 SetFormatPresets::~SetFormatPresets()
508 {
509 }
510
511 int SetFormatPresets::handle_event()
512 {
513         format_gui->thread->update();
514         return 1;
515 }
516
517 EDL* SetFormatPresets::get_edl()
518 {
519         return format_gui->thread->new_settings;
520 }
521
522
523
524 SetSampleRateTextBox::SetSampleRateTextBox(SetFormatThread *thread, int x, int y)
525  : BC_TextBox(x, y, 100, 1, (int64_t)thread->new_settings->session->sample_rate)
526 {
527         this->thread = thread;
528 }
529 int SetSampleRateTextBox::handle_event()
530 {
531         thread->new_settings->session->sample_rate = CLIP(atol(get_text()), 1, 1000000);
532         return 1;
533 }
534
535 SetChannelsTextBox::SetChannelsTextBox(SetFormatThread *thread, int x, int y)
536  : BC_TextBox(x, y, 100, 1, thread->new_settings->session->audio_channels)
537 {
538         this->thread = thread;
539 }
540 int SetChannelsTextBox::handle_event()
541 {
542         int new_channels = CLIP(atoi(get_text()), 1, MAXCHANNELS);
543
544         thread->new_settings->session->audio_channels = new_channels;
545
546
547         if(new_channels > 0)
548         {
549                 memcpy(thread->new_settings->session->achannel_positions,
550                         &thread->mwindow->preferences->channel_positions[new_channels - 1],
551                         sizeof(thread->new_settings->session->achannel_positions));
552         }
553
554
555         thread->window->canvas->draw();
556         return 1;
557 }
558
559 SetChannelsReset::SetChannelsReset(SetFormatThread *thread, int x, int y, const char *text)
560  : BC_GenericButton(x, y, text)
561 {
562         this->thread = thread;
563 }
564
565 int SetChannelsReset::handle_event()
566 {
567         int channels = thread->new_settings->session->audio_channels;
568         int *achannels = thread->new_settings->session->achannel_positions;
569         for( int i=0; i<MAX_CHANNELS; ++i )
570                 achannels[i] = default_audio_channel_position(i, channels);
571         thread->window->canvas->draw();
572         return 1;
573 }
574
575 SetChannelsCanvas::SetChannelsCanvas(MWindow *mwindow,
576         SetFormatThread *thread, int x, int y, int w, int h)
577  : BC_SubWindow(x, y, w, h)
578 {
579         this->thread = thread;
580         this->mwindow = mwindow;
581         active_channel = -1;
582         box_r = mwindow->theme->channel_position_data->get_w() / 2;
583         temp_picon = new VFrame(
584                 mwindow->theme->channel_position_data->get_w(),
585                 mwindow->theme->channel_position_data->get_h(),
586                 mwindow->theme->channel_position_data->get_color_model(),
587                 0);
588         rotater = new RotateFrame(mwindow->preferences->processors,
589                 mwindow->theme->channel_position_data->get_w(),
590                 mwindow->theme->channel_position_data->get_h());
591 }
592 SetChannelsCanvas::~SetChannelsCanvas()
593 {
594         delete temp_picon;
595         delete rotater;
596 }
597
598 int SetChannelsCanvas::draw(int angle)
599 {
600         set_color(RED);
601         //int real_w = get_w() - box_r * 2;
602         //int real_h = get_h() - box_r * 2;
603         //int real_x = box_r;
604         //int real_y = box_r;
605
606         draw_top_background(get_top_level(), 0, 0, get_w(), get_h());
607 //      draw_vframe(mwindow->theme->channel_bg_data, 0, 0);
608
609
610
611
612         int x, y, w, h;
613         char string[32];
614         set_color(mwindow->theme->channel_position_color);
615         for(int i = 0; i < thread->new_settings->session->audio_channels; i++)
616         {
617                 get_dimensions(thread->new_settings->session->achannel_positions[i],
618                         x,
619                         y,
620                         w,
621                         h);
622                 double rotate_angle = thread->new_settings->session->achannel_positions[i];
623                 rotate_angle = -rotate_angle;
624                 while(rotate_angle < 0) rotate_angle += 360;
625                 rotater->rotate(temp_picon,
626                         mwindow->theme->channel_position_data,
627                         rotate_angle,
628                         0);
629
630                 BC_Pixmap temp_pixmap(this,
631                         temp_picon,
632                         PIXMAP_ALPHA,
633                         0);
634                 draw_pixmap(&temp_pixmap, x, y);
635                 sprintf(string, "%d", i + 1);
636                 draw_text(x + 2, y + box_r * 2 - 2, string);
637         }
638
639         if(angle > -1)
640         {
641                 sprintf(string, _("%d degrees"), angle);
642                 draw_text(this->get_w() / 2 - 40, this->get_h() / 2, string);
643         }
644
645         flash();
646         return 0;
647 }
648
649 int SetChannelsCanvas::get_dimensions(int channel_position,
650         int &x,
651         int &y,
652         int &w,
653         int &h)
654 {
655 #define MARGIN 10
656         int real_w = this->get_w() - box_r * 2 - MARGIN;
657         int real_h = this->get_h() - box_r * 2 - MARGIN;
658         float corrected_position = channel_position;
659         if(corrected_position < 0) corrected_position += 360;
660         Units::polar_to_xy((float)corrected_position, real_w / 2, x, y);
661         x += real_w / 2 + MARGIN / 2;
662         y += real_h / 2 + MARGIN / 2;
663         w = box_r * 2;
664         h = box_r * 2;
665         return 0;
666 }
667
668 int SetChannelsCanvas::button_press_event()
669 {
670         if(!cursor_inside()) return 0;
671 // get active channel
672         for( int i = 0; i < thread->new_settings->session->audio_channels; i++ ) {
673                 int x, y, w, h;
674                 get_dimensions(thread->new_settings->session->achannel_positions[i], x, y, w, h);
675                 if( get_cursor_x() > x && get_cursor_y() > y &&
676                     get_cursor_x() < x + w && get_cursor_y() < y + h ) {
677                         active_channel = i;
678                         degree_offset = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
679                         degree_offset += 90;
680                         if(degree_offset >= 360) degree_offset -= 360;
681                         degree_offset -= thread->new_settings->session->achannel_positions[i];
682                         draw(thread->new_settings->session->achannel_positions[i]);
683                         return 1;
684                 }
685         }
686         return 0;
687 }
688
689 int SetChannelsCanvas::button_release_event()
690 {
691         if(active_channel >= 0)
692         {
693                 active_channel = -1;
694                 draw(-1);
695                 return 1;
696         }
697         return 0;
698 }
699
700 int SetChannelsCanvas::cursor_motion_event()
701 {
702         if(active_channel >= 0)
703         {
704 // get degrees of new channel
705                 int new_d;
706                 new_d = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
707                 new_d += 90;
708                 new_d -= degree_offset;
709
710                 while(new_d >= 360) new_d -= 360;
711                 while(new_d < 0) new_d += 360;
712
713                 if(thread->new_settings->session->achannel_positions[active_channel] != new_d)
714                 {
715                         thread->new_settings->session->achannel_positions[active_channel] = new_d;
716                         int new_channels = thread->new_settings->session->audio_channels;
717                         memcpy(&thread->mwindow->preferences->channel_positions[new_channels - 1],
718                                 thread->new_settings->session->achannel_positions,
719                                 sizeof(thread->mwindow->preferences->channel_positions[new_channels - 1]));
720                         draw(thread->new_settings->session->achannel_positions[active_channel]);
721                 }
722                 return 1;
723         }
724         return 0;
725 }
726
727
728 SetFrameRateTextBox::SetFrameRateTextBox(SetFormatThread *thread, int x, int y)
729  : BC_TextBox(x, y, 100, 1, (float)thread->new_settings->session->frame_rate)
730 {
731         this->thread = thread;
732 }
733
734 int SetFrameRateTextBox::handle_event()
735 {
736         thread->new_settings->session->frame_rate = Units::atoframerate(get_text());
737         return 1;
738 }
739
740
741 //
742 // SetVChannels::SetVChannels(SetFormatThread *thread, int x, int y)
743 //  : BC_TextBox(x, y, 100, 1, thread->channels)
744 // {
745 //      this->thread = thread;
746 // }
747 // int SetVChannels::handle_event()
748 // {
749 //      thread->channels = atol(get_text());
750 //      return 1;
751 // }
752
753
754
755
756 ScaleSizeText::ScaleSizeText(int x, int y, SetFormatThread *thread, int *output)
757  : BC_TextBox(x, y, 100, 1, *output)
758 {
759         this->thread = thread;
760         this->output = output;
761 }
762 ScaleSizeText::~ScaleSizeText()
763 {
764 }
765 int ScaleSizeText::handle_event()
766 {
767         *output = atol(get_text());
768         *output /= 2;
769         *output *= 2;
770         if(*output <= 0) *output = 2;
771         if(*output > 10000) *output = 10000;
772         *output *= -1;
773         thread->update_window();
774         return 1;
775 }
776
777
778
779 ScaleRatioText::ScaleRatioText(int x,
780         int y,
781         SetFormatThread *thread,
782         float *output)
783  : BC_TextBox(x, y, 100, 1, *output)
784 {
785         this->thread = thread;
786         this->output = output;
787 }
788 ScaleRatioText::~ScaleRatioText()
789 {
790 }
791 int ScaleRatioText::handle_event()
792 {
793         *output = atof(get_text());
794         //if(*output <= 0) *output = 1;
795         if(*output > 10000) *output = 10000;
796         if(*output < -10000) *output = -10000;
797         *output *= -1;
798         thread->update_window();
799         return 1;
800 }
801
802
803 ScaleAspectAuto::ScaleAspectAuto(int x, int y, SetFormatThread *thread)
804  : BC_CheckBox(x, y, thread->auto_aspect, _("Auto"))
805 {
806         this->thread = thread;
807 }
808
809 ScaleAspectAuto::~ScaleAspectAuto()
810 {
811 }
812
813 int ScaleAspectAuto::handle_event()
814 {
815         thread->auto_aspect = get_value();
816         thread->update_aspect();
817         return 1;
818 }
819
820 ScaleAspectText::ScaleAspectText(int x, int y, SetFormatThread *thread, float *output)
821  : BC_TextBox(x, y, 70, 1, *output)
822 {
823         this->output = output;
824         this->thread = thread;
825 }
826 ScaleAspectText::~ScaleAspectText()
827 {
828 }
829
830 int ScaleAspectText::handle_event()
831 {
832         *output = atof(get_text());
833         return 1;
834 }
835
836
837 SetFormatApply::SetFormatApply(int x, int y, SetFormatThread *thread)
838  : BC_GenericButton(x, y, _("Apply"))
839 {
840         this->thread = thread;
841 }
842
843 int SetFormatApply::handle_event()
844 {
845         thread->apply_changes();
846         return 1;
847 }
848
849
850 FormatSwapExtents::FormatSwapExtents(MWindow *mwindow,
851         SetFormatThread *thread,
852         SetFormatWindow *gui,
853         int x,
854         int y)
855  : BC_Button(x, y, mwindow->theme->get_image_set("swap_extents"))
856 {
857         this->mwindow = mwindow;
858         this->thread = thread;
859         this->gui = gui;
860         set_tooltip(_("Swap dimensions"));
861 }
862
863 int FormatSwapExtents::handle_event()
864 {
865         int w = thread->dimension[0];
866         int h = thread->dimension[1];
867         thread->dimension[0] = -h;
868         gui->dimension[0]->update((int64_t)h);
869         gui->dimension[1]->update((int64_t)w);
870         thread->update_window();
871         thread->dimension[1] = -w;
872         thread->update_window();
873         return 1;
874 }
875