change thread join strategy, fix a few leaks, fix a few bugs
[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[MAXCHANNELS * (new_channels - 1)],
155                 new_settings->session->achannel_positions,
156                 sizeof(int) * MAXCHANNELS);
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->rechannel();
163         mwindow->edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
164         mwindow->edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
165         mwindow->save_backup();
166         mwindow->undo->update_undo_after(_("set format"), LOAD_ALL);
167
168         mwindow->resync_guis();
169 }
170
171 void SetFormatThread::update()
172 {
173         window->sample_rate->update(new_settings->session->sample_rate);
174         window->channels->update((int64_t)new_settings->session->audio_channels);
175         window->frame_rate->update((float)new_settings->session->frame_rate);
176
177         switch( new_settings->session->audio_channels ) {
178         case 6:
179                 new_settings->session->achannel_positions[0] = 90;
180                 new_settings->session->achannel_positions[1] = 150;
181                 new_settings->session->achannel_positions[2] = 30;
182                 new_settings->session->achannel_positions[3] = 210;
183                 new_settings->session->achannel_positions[4] = 330;
184                 new_settings->session->achannel_positions[5] = 270;
185                 break;
186         case 2:
187                 new_settings->session->achannel_positions[0] = 180;
188                 new_settings->session->achannel_positions[1] = 0;
189                 break;
190         }
191         auto_aspect = 0;
192         window->auto_aspect->update(0);
193
194         constrain_ratio = 0;
195         dimension[0] = new_settings->session->output_w;
196         window->dimension[0]->update((int64_t)dimension[0]);
197         dimension[1] = new_settings->session->output_h;
198         window->dimension[1]->update((int64_t)dimension[1]);
199
200         ratio[0] = (float)dimension[0] / orig_dimension[0];
201         window->ratio[0]->update(ratio[0]);
202         ratio[1] = (float)dimension[1] / orig_dimension[1];
203         window->ratio[1]->update(ratio[1]);
204
205         window->aspect_w->update(new_settings->session->aspect_w);
206         window->aspect_h->update(new_settings->session->aspect_h);
207         window->interlace_pulldown->update(new_settings->session->interlace_mode);
208         window->color_model->update_value(new_settings->session->color_model);
209
210         window->canvas->draw();
211 }
212
213 void SetFormatThread::update_window()
214 {
215         int i, result, modified_item = 0, dimension_modified = 0, ratio_modified = 0;
216
217         for(i = 0, result = 0; i < 2 && !result; i++)
218         {
219                 if(dimension[i] < 0)
220                 {
221                         dimension[i] *= -1;
222                         result = 1;
223                         modified_item = i;
224                         dimension_modified = 1;
225                 }
226                 if(ratio[i] < 0)
227                 {
228                         ratio[i] *= -1;
229                         result = 1;
230                         modified_item = i;
231                         ratio_modified = 1;
232                 }
233         }
234
235         if(result)
236         {
237                 if(dimension_modified)
238                         ratio[modified_item] = (float)dimension[modified_item] / orig_dimension[modified_item];
239
240                 if(ratio_modified && !constrain_ratio)
241                 {
242                         dimension[modified_item] = (int)(orig_dimension[modified_item] * ratio[modified_item]);
243                         window->dimension[modified_item]->update((int64_t)dimension[modified_item]);
244                 }
245
246                 for(i = 0; i < 2; i++)
247                 {
248                         if(dimension_modified ||
249                                 (i != modified_item && ratio_modified))
250                         {
251                                 if(constrain_ratio) ratio[i] = ratio[modified_item];
252                                 window->ratio[i]->update(ratio[i]);
253                         }
254
255                         if(ratio_modified ||
256                                 (i != modified_item && dimension_modified))
257                         {
258                                 if(constrain_ratio)
259                                 {
260                                         dimension[i] = (int)(orig_dimension[i] * ratio[modified_item]);
261                                         window->dimension[i]->update((int64_t)dimension[i]);
262                                 }
263                         }
264                 }
265         }
266
267         update_aspect();
268 }
269
270 void SetFormatThread::update_aspect()
271 {
272         if(auto_aspect)
273         {
274                 char string[BCTEXTLEN];
275                 MWindow::create_aspect_ratio(new_settings->session->aspect_w,
276                         new_settings->session->aspect_h,
277                         dimension[0],
278                         dimension[1]);
279                 sprintf(string, "%.02f", new_settings->session->aspect_w);
280                 window->aspect_w->update(string);
281                 sprintf(string, "%.02f", new_settings->session->aspect_h);
282                 window->aspect_h->update(string);
283         }
284 }
285
286
287
288
289
290
291
292
293
294 SetFormatWindow::SetFormatWindow(MWindow *mwindow,
295         SetFormatThread *thread,
296         int x,
297         int y)
298  : BC_Window(_(PROGRAM_NAME ": Set Format"),
299         x,
300         y,
301         mwindow->theme->setformat_w,
302         mwindow->theme->setformat_h,
303         -1,
304         -1,
305         0,
306         0,
307         1)
308 {
309         this->mwindow = mwindow;
310         this->thread = thread;
311 }
312
313 void SetFormatWindow::create_objects()
314 {
315         int x = 10, y = mwindow->theme->setformat_y1;
316         BC_TextBox *textbox;
317         BC_Title *title;
318
319         lock_window("SetFormatWindow::create_objects");
320         mwindow->theme->draw_setformat_bg(this);
321
322
323
324         presets = new SetFormatPresets(mwindow,
325                 this,
326                 x,
327                 y);
328         presets->create_objects();
329         x = presets->x;
330         y = presets->y;
331
332         y = mwindow->theme->setformat_y2;
333
334         add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
335                 y,
336                 _("Audio"),
337                 LARGEFONT));
338         y = mwindow->theme->setformat_y3;
339
340         add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
341                 y,
342                 _("Samplerate:")));
343         add_subwindow(sample_rate = new SetSampleRateTextBox(thread,
344                 mwindow->theme->setformat_x2,
345                 y));
346         add_subwindow(new SampleRatePulldown(mwindow,
347                 sample_rate,
348                 mwindow->theme->setformat_x2 + sample_rate->get_w(),
349                 y));
350
351         y += mwindow->theme->setformat_margin;
352         add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
353                 y,
354                 _("Channels:")));
355         add_subwindow(channels = new SetChannelsTextBox(thread,
356                 mwindow->theme->setformat_x2,
357                 y));
358         add_subwindow(new BC_ITumbler(channels,
359                 1,
360                 MAXCHANNELS,
361                 mwindow->theme->setformat_x2 + channels->get_w(),
362                 y));
363
364         y += mwindow->theme->setformat_margin;
365         add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
366                 y,
367                 _("Channel positions:")));
368         y += mwindow->theme->setformat_margin;
369         add_subwindow(canvas = new SetChannelsCanvas(mwindow,
370                 thread,
371                 mwindow->theme->setformat_channels_x,
372                 mwindow->theme->setformat_channels_y,
373                 mwindow->theme->setformat_channels_w,
374                 mwindow->theme->setformat_channels_h));
375         canvas->draw();
376
377
378
379
380
381
382
383
384
385         y = mwindow->theme->setformat_y2;
386         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
387                 y,
388                 _("Video"),
389                 LARGEFONT));
390
391         y = mwindow->theme->setformat_y3;
392         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
393                 y,
394                 _("Frame rate:")));
395         add_subwindow(frame_rate = new SetFrameRateTextBox(thread,
396                 mwindow->theme->setformat_x4,
397                 y));
398         add_subwindow(new FrameRatePulldown(mwindow,
399                 frame_rate,
400                 mwindow->theme->setformat_x4 + frame_rate->get_w(),
401                 y));
402
403         y += mwindow->theme->setformat_margin;
404         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
405                 y,
406                 _("Canvas size:")));
407
408         y += mwindow->theme->setformat_margin;
409         add_subwindow(title = new BC_Title(mwindow->theme->setformat_x3, y, _("Width:")));
410         add_subwindow(dimension[0] = new ScaleSizeText(mwindow->theme->setformat_x4,
411                 y,
412                 thread,
413                 &(thread->dimension[0])));
414
415         y += mwindow->theme->setformat_margin;
416         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, y, _("Height:")));
417         add_subwindow(dimension[1] = new ScaleSizeText(mwindow->theme->setformat_x4,
418                 y,
419                 thread,
420                 &(thread->dimension[1])));
421
422         x = mwindow->theme->setformat_x4 + dimension[0]->get_w();
423         FrameSizePulldown *pulldown;
424         add_subwindow(pulldown = new FrameSizePulldown(mwindow->theme,
425                 dimension[0],
426                 dimension[1],
427                 x,
428                 y - mwindow->theme->setformat_margin));
429
430         add_subwindow(new FormatSwapExtents(mwindow,
431                 thread,
432                 this,
433                 x + pulldown->get_w() + 5,
434                 y - mwindow->theme->setformat_margin));
435
436         y += mwindow->theme->setformat_margin;
437         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
438                 y,
439                 _("W Ratio:")));
440         add_subwindow(ratio[0] = new ScaleRatioText(mwindow->theme->setformat_x4,
441                 y,
442                 thread,
443                 &(thread->ratio[0])));
444
445         y += mwindow->theme->setformat_margin;
446         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
447                 y,
448                 _("H Ratio:")));
449         add_subwindow(ratio[1] = new ScaleRatioText(mwindow->theme->setformat_x4,
450                 y,
451                 thread,
452                 &(thread->ratio[1])));
453
454         y += mwindow->theme->setformat_margin;
455         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
456                 y,
457                 _("Color model:")));
458         x = mwindow->theme->setformat_x4;
459         add_subwindow(textbox = new BC_TextBox(x,
460                 y,
461                 100,
462                 1,
463                 ""));
464         x += textbox->get_w();
465         add_subwindow(color_model = new ColormodelPulldown(mwindow,
466                 textbox,
467                 &thread->new_settings->session->color_model,
468                 x,
469                 y));
470
471         y += mwindow->theme->setformat_margin;
472         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
473                 y,
474                 _("Aspect ratio:")));
475         y += mwindow->theme->setformat_margin;
476         x = mwindow->theme->setformat_x3;
477         add_subwindow(aspect_w = new ScaleAspectText(x,
478                 y,
479                 thread,
480                 &(thread->new_settings->session->aspect_w)));
481         x += aspect_w->get_w() + 5;
482         add_subwindow(new BC_Title(x, y, _(":")));
483         x += 10;
484         add_subwindow(aspect_h = new ScaleAspectText(x,
485                 y,
486                 thread,
487                 &(thread->new_settings->session->aspect_h)));
488         x += aspect_h->get_w();
489         add_subwindow(new AspectPulldown(mwindow,
490                 aspect_w,
491                 aspect_h,
492                 x,
493                 y));
494         x += 30;
495         add_subwindow(auto_aspect = new ScaleAspectAuto(x, y, thread));
496         y += mwindow->theme->setformat_margin;
497
498         // --------------------
499         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
500                 y,
501                 _("Interlace mode:")));
502         add_subwindow(textbox = new BC_TextBox(mwindow->theme->setformat_x4,
503                 y,
504                 140,
505                 1,
506                 ""));
507         add_subwindow(interlace_pulldown = new InterlacemodePulldown(mwindow,
508                 textbox,
509                 &(thread->new_settings->session->interlace_mode),
510                 (ArrayList<BC_ListBoxItem*>*)&mwindow->interlace_project_modes,
511                 mwindow->theme->setformat_x4 + textbox->get_w(),
512                 y));
513         y += mwindow->theme->setformat_margin;
514
515
516         BC_OKTextButton *ok;
517         BC_CancelTextButton *cancel;
518         add_subwindow(ok = new BC_OKTextButton(this));
519         add_subwindow(cancel = new BC_CancelTextButton(this));
520         add_subwindow(new SetFormatApply((ok->get_x() + cancel->get_x()) / 2,
521                 ok->get_y(),
522                 thread));
523         flash();
524         show_window();
525         unlock_window();
526 }
527
528 const char* SetFormatWindow::get_preset_text()
529 {
530         return "";
531 }
532
533
534 SetFormatPresets::SetFormatPresets(MWindow *mwindow,
535         SetFormatWindow *gui,
536         int x,
537         int y)
538  : FormatPresets(mwindow, 0, gui, x, y)
539 {
540
541 }
542
543 SetFormatPresets::~SetFormatPresets()
544 {
545 }
546
547 int SetFormatPresets::handle_event()
548 {
549         format_gui->thread->update();
550         return 1;
551 }
552
553 EDL* SetFormatPresets::get_edl()
554 {
555         return format_gui->thread->new_settings;
556 }
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572 SetSampleRateTextBox::SetSampleRateTextBox(SetFormatThread *thread, int x, int y)
573  : BC_TextBox(x, y, 100, 1, (int64_t)thread->new_settings->session->sample_rate)
574 {
575         this->thread = thread;
576 }
577 int SetSampleRateTextBox::handle_event()
578 {
579         thread->new_settings->session->sample_rate = CLIP(atol(get_text()), 1, 1000000);
580         return 1;
581 }
582
583 SetChannelsTextBox::SetChannelsTextBox(SetFormatThread *thread, int x, int y)
584  : BC_TextBox(x, y, 100, 1, thread->new_settings->session->audio_channels)
585 {
586         this->thread = thread;
587 }
588 int SetChannelsTextBox::handle_event()
589 {
590         int new_channels = CLIP(atoi(get_text()), 1, MAXCHANNELS);
591
592         thread->new_settings->session->audio_channels = new_channels;
593
594
595         if(new_channels > 0)
596         {
597                 memcpy(thread->new_settings->session->achannel_positions,
598                         &thread->mwindow->preferences->channel_positions[MAXCHANNELS * (new_channels - 1)],
599                         sizeof(int) * MAXCHANNELS);
600         }
601
602
603         thread->window->canvas->draw();
604         return 1;
605 }
606
607
608 SetChannelsCanvas::SetChannelsCanvas(MWindow *mwindow,
609         SetFormatThread *thread,
610         int x,
611         int y,
612         int w,
613         int h)
614  : BC_SubWindow(x,
615         y,
616         w,
617         h)
618 {
619         this->thread = thread;
620         this->mwindow = mwindow;
621         active_channel = -1;
622         box_r = mwindow->theme->channel_position_data->get_w() / 2;
623         temp_picon = new VFrame(0,
624                 -1,
625                 mwindow->theme->channel_position_data->get_w(),
626                 mwindow->theme->channel_position_data->get_h(),
627                 mwindow->theme->channel_position_data->get_color_model(),
628                 -1);
629         rotater = new RotateFrame(mwindow->preferences->processors,
630                 mwindow->theme->channel_position_data->get_w(),
631                 mwindow->theme->channel_position_data->get_h());
632 }
633 SetChannelsCanvas::~SetChannelsCanvas()
634 {
635         delete temp_picon;
636         delete rotater;
637 }
638
639 int SetChannelsCanvas::draw(int angle)
640 {
641         set_color(RED);
642         //int real_w = get_w() - box_r * 2;
643         //int real_h = get_h() - box_r * 2;
644         //int real_x = box_r;
645         //int real_y = box_r;
646
647         draw_top_background(get_top_level(), 0, 0, get_w(), get_h());
648 //      draw_vframe(mwindow->theme->channel_bg_data, 0, 0);
649
650
651
652
653         int x, y, w, h;
654         char string[32];
655         set_color(mwindow->theme->channel_position_color);
656         for(int i = 0; i < thread->new_settings->session->audio_channels; i++)
657         {
658                 get_dimensions(thread->new_settings->session->achannel_positions[i],
659                         x,
660                         y,
661                         w,
662                         h);
663                 double rotate_angle = thread->new_settings->session->achannel_positions[i];
664                 rotate_angle = -rotate_angle;
665                 while(rotate_angle < 0) rotate_angle += 360;
666                 rotater->rotate(temp_picon,
667                         mwindow->theme->channel_position_data,
668                         rotate_angle,
669                         0);
670
671                 BC_Pixmap temp_pixmap(this,
672                         temp_picon,
673                         PIXMAP_ALPHA,
674                         0);
675                 draw_pixmap(&temp_pixmap, x, y);
676                 sprintf(string, "%d", i + 1);
677                 draw_text(x + 2, y + box_r * 2 - 2, string);
678         }
679
680         if(angle > -1)
681         {
682                 sprintf(string, _("%d degrees"), angle);
683                 draw_text(this->get_w() / 2 - 40, this->get_h() / 2, string);
684         }
685
686         flash();
687         return 0;
688 }
689
690 int SetChannelsCanvas::get_dimensions(int channel_position,
691         int &x,
692         int &y,
693         int &w,
694         int &h)
695 {
696 #define MARGIN 10
697         int real_w = this->get_w() - box_r * 2 - MARGIN;
698         int real_h = this->get_h() - box_r * 2 - MARGIN;
699         float corrected_position = channel_position;
700         if(corrected_position < 0) corrected_position += 360;
701         Units::polar_to_xy((float)corrected_position, real_w / 2, x, y);
702         x += real_w / 2 + MARGIN / 2;
703         y += real_h / 2 + MARGIN / 2;
704         w = box_r * 2;
705         h = box_r * 2;
706         return 0;
707 }
708
709 int SetChannelsCanvas::button_press_event()
710 {
711         if(!cursor_inside()) return 0;
712 // get active channel
713         for( int i = 0; i < thread->new_settings->session->audio_channels; i++ ) {
714                 int x, y, w, h;
715                 get_dimensions(thread->new_settings->session->achannel_positions[i], x, y, w, h);
716                 if( get_cursor_x() > x && get_cursor_y() > y &&
717                     get_cursor_x() < x + w && get_cursor_y() < y + h ) {
718                         active_channel = i;
719                         degree_offset = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
720                         degree_offset += 90;
721                         if(degree_offset >= 360) degree_offset -= 360;
722                         degree_offset -= thread->new_settings->session->achannel_positions[i];
723                         draw(thread->new_settings->session->achannel_positions[i]);
724                         return 1;
725                 }
726         }
727         return 0;
728 }
729
730 int SetChannelsCanvas::button_release_event()
731 {
732         if(active_channel >= 0)
733         {
734                 active_channel = -1;
735                 draw(-1);
736                 return 1;
737         }
738         return 0;
739 }
740
741 int SetChannelsCanvas::cursor_motion_event()
742 {
743         if(active_channel >= 0)
744         {
745 // get degrees of new channel
746                 int new_d;
747                 new_d = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
748                 new_d += 90;
749                 new_d -= degree_offset;
750
751                 while(new_d >= 360) new_d -= 360;
752                 while(new_d < 0) new_d += 360;
753
754                 if(thread->new_settings->session->achannel_positions[active_channel] != new_d)
755                 {
756                         thread->new_settings->session->achannel_positions[active_channel] = new_d;
757                         int new_channels = thread->new_settings->session->audio_channels;
758                         memcpy(&thread->mwindow->preferences->channel_positions[MAXCHANNELS * (new_channels - 1)],
759                                 thread->new_settings->session->achannel_positions,
760                                 sizeof(int) * MAXCHANNELS);
761                         draw(thread->new_settings->session->achannel_positions[active_channel]);
762                 }
763                 return 1;
764         }
765         return 0;
766 }
767
768
769
770
771
772
773
774
775
776 SetFrameRateTextBox::SetFrameRateTextBox(SetFormatThread *thread, int x, int y)
777  : BC_TextBox(x, y, 100, 1, (float)thread->new_settings->session->frame_rate)
778 {
779         this->thread = thread;
780 }
781
782 int SetFrameRateTextBox::handle_event()
783 {
784         thread->new_settings->session->frame_rate = Units::atoframerate(get_text());
785         return 1;
786 }
787
788
789 //
790 // SetVChannels::SetVChannels(SetFormatThread *thread, int x, int y)
791 //  : BC_TextBox(x, y, 100, 1, thread->channels)
792 // {
793 //      this->thread = thread;
794 // }
795 // int SetVChannels::handle_event()
796 // {
797 //      thread->channels = atol(get_text());
798 //      return 1;
799 // }
800
801
802
803
804 ScaleSizeText::ScaleSizeText(int x, int y, SetFormatThread *thread, int *output)
805  : BC_TextBox(x, y, 100, 1, *output)
806 {
807         this->thread = thread;
808         this->output = output;
809 }
810 ScaleSizeText::~ScaleSizeText()
811 {
812 }
813 int ScaleSizeText::handle_event()
814 {
815         *output = atol(get_text());
816         *output /= 2;
817         *output *= 2;
818         if(*output <= 0) *output = 2;
819         if(*output > 10000) *output = 10000;
820         *output *= -1;
821         thread->update_window();
822         return 1;
823 }
824
825
826
827 ScaleRatioText::ScaleRatioText(int x,
828         int y,
829         SetFormatThread *thread,
830         float *output)
831  : BC_TextBox(x, y, 100, 1, *output)
832 {
833         this->thread = thread;
834         this->output = output;
835 }
836 ScaleRatioText::~ScaleRatioText()
837 {
838 }
839 int ScaleRatioText::handle_event()
840 {
841         *output = atof(get_text());
842         //if(*output <= 0) *output = 1;
843         if(*output > 10000) *output = 10000;
844         if(*output < -10000) *output = -10000;
845         *output *= -1;
846         thread->update_window();
847         return 1;
848 }
849
850
851
852 ScaleAspectAuto::ScaleAspectAuto(int x, int y, SetFormatThread *thread)
853  : BC_CheckBox(x, y, thread->auto_aspect, _("Auto"))
854 {
855         this->thread = thread;
856 }
857
858 ScaleAspectAuto::~ScaleAspectAuto()
859 {
860 }
861
862 int ScaleAspectAuto::handle_event()
863 {
864         thread->auto_aspect = get_value();
865         thread->update_aspect();
866         return 1;
867 }
868
869 ScaleAspectText::ScaleAspectText(int x, int y, SetFormatThread *thread, float *output)
870  : BC_TextBox(x, y, 70, 1, *output)
871 {
872         this->output = output;
873         this->thread = thread;
874 }
875 ScaleAspectText::~ScaleAspectText()
876 {
877 }
878
879 int ScaleAspectText::handle_event()
880 {
881         *output = atof(get_text());
882         return 1;
883 }
884
885
886
887
888
889
890 SetFormatApply::SetFormatApply(int x, int y, SetFormatThread *thread)
891  : BC_GenericButton(x, y, _("Apply"))
892 {
893         this->thread = thread;
894 }
895
896 int SetFormatApply::handle_event()
897 {
898         thread->apply_changes();
899         return 1;
900 }
901
902
903
904
905
906
907
908
909
910
911
912
913
914 FormatSwapExtents::FormatSwapExtents(MWindow *mwindow,
915         SetFormatThread *thread,
916         SetFormatWindow *gui,
917         int x,
918         int y)
919  : BC_Button(x, y, mwindow->theme->get_image_set("swap_extents"))
920 {
921         this->mwindow = mwindow;
922         this->thread = thread;
923         this->gui = gui;
924         set_tooltip(_("Swap dimensions"));
925 }
926
927 int FormatSwapExtents::handle_event()
928 {
929         int w = thread->dimension[0];
930         int h = thread->dimension[1];
931         thread->dimension[0] = -h;
932         gui->dimension[0]->update((int64_t)h);
933         gui->dimension[1]->update((int64_t)w);
934         thread->update_window();
935         thread->dimension[1] = -w;
936         thread->update_window();
937         return 1;
938 }
939
940
941
942