Credit Andrew - fix vorbis audio which was scratchy and ensure aging plugin does...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / setformat.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
5  * Copyright (C) 2003-2016 Cinelerra CV contributors
6  *
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.
11  *
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.
16  *
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
20  *
21  */
22
23 #include "clip.h"
24 #include "cwindow.h"
25 #include "cwindowgui.h"
26 #include "datatype.h"
27 #include "bchash.h"
28 #include "edl.h"
29 #include "edlsession.h"
30 #include "formatpresets.h"
31 #include "language.h"
32 #include "levelwindow.h"
33 #include "levelwindowgui.h"
34 #include "mainerror.h"
35 #include "mainundo.h"
36 #include "mutex.h"
37 #include "mwindow.h"
38 #include "mwindowgui.h"
39 #include "new.h"
40 #include "preferences.h"
41 #include "rotateframe.h"
42 #include "setformat.h"
43 #include "theme.h"
44 #include "vframe.h"
45 #include "vwindow.h"
46 #include "vwindowgui.h"
47
48
49
50 SetFormat::SetFormat(MWindow *mwindow)
51  : BC_MenuItem(_("Format..."), _("Shift-F"), 'F')
52 {
53         set_shift(1);
54         this->mwindow = mwindow;
55         thread = new SetFormatThread(mwindow);
56 }
57
58 SetFormat::~SetFormat()
59 {
60         delete thread;
61 }
62
63 int SetFormat::handle_event()
64 {
65         if(!thread->running())
66         {
67                 thread->start();
68         }
69         else
70         {
71 // window_lock has to be locked but window can't be locked until after
72 // it is known to exist, so we neglect window_lock for now
73                 if(thread->window)
74                 {
75                         thread->window_lock->lock("SetFormat::handle_event");
76                         thread->window->lock_window("SetFormat::handle_event");
77                         thread->window->raise_window();
78                         thread->window->unlock_window();
79                         thread->window_lock->unlock();
80                 }
81         }
82         return 1;
83 }
84
85 SetFormatThread::SetFormatThread(MWindow *mwindow)
86  : Thread(1, 0, 0)
87 {
88         this->mwindow = mwindow;
89         window_lock = new Mutex("SetFormatThread::window_lock");
90         window = 0;
91 }
92
93 SetFormatThread::~SetFormatThread()
94 {
95         if( running() ) {
96                 window->set_done(1);
97                 cancel();
98         }
99         join();
100         delete window_lock;
101 }
102
103 void SetFormatThread::run()
104 {
105         orig_dimension[0] = dimension[0] = mwindow->edl->session->output_w;
106         orig_dimension[1] = dimension[1] = mwindow->edl->session->output_h;
107         auto_aspect = mwindow->defaults->get("AUTOASPECT", 0);
108         constrain_ratio = 0;
109         ratio[0] = ratio[1] = 1;
110
111         new_settings = new EDL;
112         new_settings->create_objects();
113         new_settings->copy_session(mwindow->edl);
114
115 // This locks mwindow, so it must be done outside window_lock
116         int x = mwindow->gui->get_abs_cursor_x(1) - mwindow->theme->setformat_w / 2;
117         int y = mwindow->gui->get_abs_cursor_y(1) - mwindow->theme->setformat_h / 2;
118
119         window_lock->lock("SetFormatThread::run 1");
120         window = new SetFormatWindow(mwindow, this, x, y);
121         window->create_objects();
122         window_lock->unlock();
123
124         int result = window->run_window();
125
126
127         window_lock->lock("SetFormatThread::run 2");
128         delete window;
129         window = 0;
130         window_lock->unlock();
131
132
133         if(!result)
134         {
135                 apply_changes();
136         }
137
138         mwindow->defaults->update("AUTOASPECT", auto_aspect);
139         new_settings->Garbage::remove_user();
140 }
141
142 void SetFormatThread::apply_changes()
143 {
144         double new_samplerate = new_settings->session->sample_rate;
145         double old_samplerate = mwindow->edl->session->sample_rate;
146         double new_framerate = new_settings->session->frame_rate;
147         double old_framerate = mwindow->edl->session->frame_rate;
148         int new_channels = new_settings->session->audio_channels;
149         CLAMP(new_channels, 1, MAXCHANNELS);
150
151
152
153         mwindow->undo->update_undo_before();
154
155         memcpy(&mwindow->preferences->channel_positions[new_channels - 1],
156                 new_settings->session->achannel_positions,
157                 sizeof(mwindow->preferences->channel_positions[new_channels - 1]));
158
159
160         mwindow->edl->copy_session(new_settings, 1);
161         mwindow->edl->session->output_w = dimension[0];
162         mwindow->edl->session->output_h = dimension[1];
163         mwindow->edl->retrack();
164         mwindow->edl->rechannel();
165         mwindow->edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
166         mwindow->edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
167         mwindow->save_backup();
168         mwindow->undo->update_undo_after(_("set format"), LOAD_ALL);
169
170         mwindow->resync_guis();
171 }
172
173 void SetFormatThread::update()
174 {
175         window->sample_rate->update(new_settings->session->sample_rate);
176         window->channels->update((int64_t)new_settings->session->audio_channels);
177         window->frame_rate->update((float)new_settings->session->frame_rate);
178
179         auto_aspect = 0;
180         window->auto_aspect->update(0);
181
182         constrain_ratio = 0;
183         dimension[0] = new_settings->session->output_w;
184         window->dimension[0]->update((int64_t)dimension[0]);
185         dimension[1] = new_settings->session->output_h;
186         window->dimension[1]->update((int64_t)dimension[1]);
187
188         ratio[0] = (float)dimension[0] / orig_dimension[0];
189         window->ratio[0]->update(ratio[0]);
190         ratio[1] = (float)dimension[1] / orig_dimension[1];
191         window->ratio[1]->update(ratio[1]);
192
193         window->aspect_w->update(new_settings->session->aspect_w);
194         window->aspect_h->update(new_settings->session->aspect_h);
195         window->interlace_pulldown->update(new_settings->session->interlace_mode);
196         window->color_model->update_value(new_settings->session->color_model);
197
198         window->canvas->draw();
199 }
200
201 void SetFormatThread::update_window()
202 {
203         int i, result, modified_item = 0, dimension_modified = 0, ratio_modified = 0;
204
205         for(i = 0, result = 0; i < 2 && !result; i++)
206         {
207                 if(dimension[i] < 0)
208                 {
209                         dimension[i] *= -1;
210                         result = 1;
211                         modified_item = i;
212                         dimension_modified = 1;
213                 }
214                 if(ratio[i] < 0)
215                 {
216                         ratio[i] *= -1;
217                         result = 1;
218                         modified_item = i;
219                         ratio_modified = 1;
220                 }
221         }
222
223         if(result)
224         {
225                 if(dimension_modified)
226                         ratio[modified_item] = (float)dimension[modified_item] / orig_dimension[modified_item];
227
228                 if(ratio_modified && !constrain_ratio)
229                 {
230                         dimension[modified_item] = (int)(orig_dimension[modified_item] * ratio[modified_item]);
231                         window->dimension[modified_item]->update((int64_t)dimension[modified_item]);
232                 }
233
234                 for(i = 0; i < 2; i++)
235                 {
236                         if(dimension_modified ||
237                                 (i != modified_item && ratio_modified))
238                         {
239                                 if(constrain_ratio) ratio[i] = ratio[modified_item];
240                                 window->ratio[i]->update(ratio[i]);
241                         }
242
243                         if(ratio_modified ||
244                                 (i != modified_item && dimension_modified))
245                         {
246                                 if(constrain_ratio)
247                                 {
248                                         dimension[i] = (int)(orig_dimension[i] * ratio[modified_item]);
249                                         window->dimension[i]->update((int64_t)dimension[i]);
250                                 }
251                         }
252                 }
253         }
254
255         update_aspect();
256 }
257
258 void SetFormatThread::update_aspect()
259 {
260         if(auto_aspect)
261         {
262                 char string[BCTEXTLEN];
263                 MWindow::create_aspect_ratio(new_settings->session->aspect_w,
264                         new_settings->session->aspect_h,
265                         dimension[0],
266                         dimension[1]);
267                 sprintf(string, "%.02f", new_settings->session->aspect_w);
268                 window->aspect_w->update(string);
269                 sprintf(string, "%.02f", new_settings->session->aspect_h);
270                 window->aspect_h->update(string);
271         }
272 }
273
274
275 SetFormatWindow::SetFormatWindow(MWindow *mwindow,
276         SetFormatThread *thread, int x, int y)
277  : BC_Window(_(PROGRAM_NAME ": Set Format"), x, y,
278         mwindow->theme->setformat_w, mwindow->theme->setformat_h,
279         -1, -1, 0, 0, 1)
280 {
281         this->mwindow = mwindow;
282         this->thread = thread;
283         presets = 0;
284 // *** CONTEXT_HELP ***
285         context_help_set_keyword("Project and Media Attributes");
286 }
287 SetFormatWindow::~SetFormatWindow()
288 {
289         delete presets;
290 }
291
292 /* W Ratio, H Ratio
293 Sets the ratio of the new canvas size (W, H) to the old (previous) canvas size (W, H). 
294 The new canvas size is recalculated based upon a certain factor in the W Ratio, 
295 H Ratio fields. A practical use-case: The current resolution is 640x480, and for some reason 
296 you want it to be 1.33 times wider. You don't have to calculate what 640x1.33 is; 
297 you type 1.33 into the "W" input instead, and Cinelerra calculates it for you. */
298
299 void SetFormatWindow::create_objects()
300 {
301         lock_window("SetFormatWindow::create_objects");
302         int x = xS(10), y = mwindow->theme->setformat_y1;
303         BC_TextBox *textbox;
304         BC_Title *title;
305         mwindow->theme->draw_setformat_bg(this);
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, 0, 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(channels_reset = 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, y, xS(100), 1, ""));
424         x += textbox->get_w();
425         add_subwindow(color_model = new ColormodelPulldown(mwindow, textbox,
426                 &thread->new_settings->session->color_model, x, y));
427
428         y += mwindow->theme->setformat_margin;
429         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
430                 y,
431                 _("Display Aspect ratio:")));
432         y += mwindow->theme->setformat_margin;
433         x = mwindow->theme->setformat_x3;
434         add_subwindow(aspect_w = new ScaleAspectText(x, y, thread,
435                 &(thread->new_settings->session->aspect_w)));
436         x += aspect_w->get_w() + xS(5);
437         add_subwindow(new BC_Title(x, y, ":"));
438         x += xS(10);
439         add_subwindow(aspect_h = new ScaleAspectText(x,
440                 y,
441                 thread,
442                 &(thread->new_settings->session->aspect_h)));
443         x += aspect_h->get_w();
444         add_subwindow(new AspectPulldown(mwindow,
445                 aspect_w,
446                 aspect_h,
447                 x,
448                 y));
449         x += xS(30);
450         add_subwindow(auto_aspect = new ScaleAspectAuto(x, y, thread));
451         y += mwindow->theme->setformat_margin;
452
453         // --------------------
454         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
455                 y,
456                 _("Interlace mode:")));
457         add_subwindow(textbox = new BC_TextBox(mwindow->theme->setformat_x4, y,
458                 xS(140), 1, ""));
459         add_subwindow(interlace_pulldown = new InterlacemodePulldown(mwindow,
460                 textbox, &(thread->new_settings->session->interlace_mode),
461                 (ArrayList<BC_ListBoxItem*>*)&mwindow->interlace_project_modes,
462                 mwindow->theme->setformat_x4 + textbox->get_w(), y));
463         y += mwindow->theme->setformat_margin;
464         
465         add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
466                y+10,
467                _("Note: W/H ratio fields means multipliers \nrelative to previous canvas size \n")));
468
469         BC_OKTextButton *ok;
470         BC_CancelTextButton *cancel;
471         add_subwindow(ok = new BC_OKTextButton(this));
472         add_subwindow(cancel = new BC_CancelTextButton(this));
473         add_subwindow(new SetFormatApply((ok->get_x() + cancel->get_x()) / 2,
474                 ok->get_y(), thread));
475         flash();
476         show_window();
477         unlock_window();
478 }
479
480 const char* SetFormatWindow::get_preset_text()
481 {
482         return "";
483 }
484
485
486 SetFormatPresets::SetFormatPresets(MWindow *mwindow,
487         SetFormatWindow *gui,
488         int x,
489         int y)
490  : FormatPresets(mwindow, 0, gui, x, y)
491 {
492
493 }
494
495 SetFormatPresets::~SetFormatPresets()
496 {
497 }
498
499 int SetFormatPresets::handle_event()
500 {
501         format_gui->thread->update();
502         return format_gui->channels_reset->handle_event();
503 }
504
505 EDL* SetFormatPresets::get_edl()
506 {
507         return format_gui->thread->new_settings;
508 }
509
510
511
512 SetSampleRateTextBox::SetSampleRateTextBox(SetFormatThread *thread, int x, int y)
513  : BC_TextBox(x, y, xS(100), 1, (int64_t)thread->new_settings->session->sample_rate)
514 {
515         this->thread = thread;
516 }
517 int SetSampleRateTextBox::handle_event()
518 {
519         thread->new_settings->session->sample_rate = CLIP(atol(get_text()), 1, 1000000);
520         return 1;
521 }
522
523 SetChannelsTextBox::SetChannelsTextBox(SetFormatThread *thread, int x, int y)
524  : BC_TextBox(x, y, xS(100), 1, thread->new_settings->session->audio_channels)
525 {
526         this->thread = thread;
527 }
528 int SetChannelsTextBox::handle_event()
529 {
530         int new_channels = CLIP(atoi(get_text()), 0, MAXCHANNELS);
531         thread->new_settings->session->audio_channels = new_channels;
532         if(new_channels > 0) {
533                 memcpy(thread->new_settings->session->achannel_positions,
534                         &thread->mwindow->preferences->channel_positions[new_channels - 1],
535                         sizeof(thread->new_settings->session->achannel_positions));
536         }
537
538         thread->window->canvas->draw();
539         return 1;
540 }
541
542 SetChannelsReset::SetChannelsReset(SetFormatThread *thread, int x, int y, const char *text)
543  : BC_GenericButton(x, y, text)
544 {
545         this->thread = thread;
546 }
547
548 int SetChannelsReset::handle_event()
549 {
550         int channels = thread->new_settings->session->audio_channels;
551         int *achannels = thread->new_settings->session->achannel_positions;
552         for( int i=0; i<MAX_CHANNELS; ++i )
553                 achannels[i] = default_audio_channel_position(i, channels);
554         thread->window->canvas->draw();
555         return 1;
556 }
557
558 SetChannelsCanvas::SetChannelsCanvas(MWindow *mwindow,
559         SetFormatThread *thread, int x, int y, int w, int h)
560  : BC_SubWindow(x, y, w, h)
561 {
562         this->thread = thread;
563         this->mwindow = mwindow;
564         active_channel = -1;
565         box_r = mwindow->theme->channel_position_data->get_w() / 2;
566         temp_picon = new VFrame(
567                 mwindow->theme->channel_position_data->get_w(),
568                 mwindow->theme->channel_position_data->get_h(),
569                 mwindow->theme->channel_position_data->get_color_model(),
570                 0);
571         rotater = new RotateFrame(mwindow->preferences->processors,
572                 mwindow->theme->channel_position_data->get_w(),
573                 mwindow->theme->channel_position_data->get_h());
574 }
575 SetChannelsCanvas::~SetChannelsCanvas()
576 {
577         delete temp_picon;
578         delete rotater;
579 }
580
581 int SetChannelsCanvas::draw(int angle)
582 {
583         set_color(RED);
584         //int real_w = get_w() - box_r * 2;
585         //int real_h = get_h() - box_r * 2;
586         //int real_x = box_r;
587         //int real_y = box_r;
588
589         draw_top_background(get_top_level(), 0, 0, get_w(), get_h());
590 //      draw_vframe(mwindow->theme->channel_bg_data, 0, 0);
591
592
593
594
595         int x, y, w, h;
596         char string[32];
597         set_color(mwindow->theme->channel_position_color);
598         for(int i = 0; i < thread->new_settings->session->audio_channels; i++)
599         {
600                 get_dimensions(thread->new_settings->session->achannel_positions[i],
601                         x, y, w, h);
602                 double rotate_angle = thread->new_settings->session->achannel_positions[i];
603                 rotate_angle = -rotate_angle;
604                 while(rotate_angle < 0) rotate_angle += 360;
605                 rotater->rotate(temp_picon,
606                         mwindow->theme->channel_position_data,
607                         rotate_angle,
608                         0);
609
610                 BC_Pixmap temp_pixmap(this,
611                         temp_picon,
612                         PIXMAP_ALPHA,
613                         0);
614                 draw_pixmap(&temp_pixmap, x, y);
615                 sprintf(string, "%d", i + 1);
616                 draw_text(x + 2, y + box_r * 2 - 2, string);
617         }
618
619         if(angle > -1)
620         {
621                 sprintf(string, _("%d degrees"), angle);
622                 draw_text(this->get_w() / 2 - 40, this->get_h() / 2, string);
623         }
624
625         flash();
626         return 0;
627 }
628
629 int SetChannelsCanvas::get_dimensions(int channel_position,
630                 int &x, int &y, int &w, int &h)
631 {
632         int xs10 = xS(10), ys10 = yS(10);
633         int real_w = this->get_w() - box_r * 2 - xs10;
634         int real_h = this->get_h() - box_r * 2 - ys10;
635         float corrected_position = channel_position;
636         if(corrected_position < 0) corrected_position += 360;
637         Units::polar_to_xy((float)corrected_position, real_w / 2, x, y);
638         x += real_w / 2 + xs10 / 2;
639         y += real_h / 2 + ys10 / 2;
640         w = box_r * 2;
641         h = box_r * 2;
642         return 0;
643 }
644
645 int SetChannelsCanvas::button_press_event()
646 {
647         if(!cursor_inside()) return 0;
648 // get active channel
649         for( int i = 0; i < thread->new_settings->session->audio_channels; i++ ) {
650                 int x, y, w, h;
651                 get_dimensions(thread->new_settings->session->achannel_positions[i], x, y, w, h);
652                 if( get_cursor_x() > x && get_cursor_y() > y &&
653                     get_cursor_x() < x + w && get_cursor_y() < y + h ) {
654                         active_channel = i;
655                         degree_offset = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
656                         degree_offset += 90;
657                         if(degree_offset >= 360) degree_offset -= 360;
658                         degree_offset -= thread->new_settings->session->achannel_positions[i];
659                         draw(thread->new_settings->session->achannel_positions[i]);
660                         return 1;
661                 }
662         }
663         return 0;
664 }
665
666 int SetChannelsCanvas::button_release_event()
667 {
668         if(active_channel >= 0)
669         {
670                 active_channel = -1;
671                 draw(-1);
672                 return 1;
673         }
674         return 0;
675 }
676
677 int SetChannelsCanvas::cursor_motion_event()
678 {
679         if(active_channel >= 0)
680         {
681 // get degrees of new channel
682                 int new_d;
683                 new_d = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
684                 new_d += 90;
685                 new_d -= degree_offset;
686
687                 while(new_d >= 360) new_d -= 360;
688                 while(new_d < 0) new_d += 360;
689
690                 if(thread->new_settings->session->achannel_positions[active_channel] != new_d)
691                 {
692                         thread->new_settings->session->achannel_positions[active_channel] = new_d;
693                         int new_channels = thread->new_settings->session->audio_channels;
694                         memcpy(&thread->mwindow->preferences->channel_positions[new_channels - 1],
695                                 thread->new_settings->session->achannel_positions,
696                                 sizeof(thread->mwindow->preferences->channel_positions[new_channels - 1]));
697                         draw(thread->new_settings->session->achannel_positions[active_channel]);
698                 }
699                 return 1;
700         }
701         return 0;
702 }
703
704
705 SetFrameRateTextBox::SetFrameRateTextBox(SetFormatThread *thread, int x, int y)
706  : BC_TextBox(x, y, xS(100), 1, (float)thread->new_settings->session->frame_rate)
707 {
708         this->thread = thread;
709 }
710
711 int SetFrameRateTextBox::handle_event()
712 {
713         thread->new_settings->session->frame_rate = Units::atoframerate(get_text());
714         return 1;
715 }
716
717
718 //
719 // SetVChannels::SetVChannels(SetFormatThread *thread, int x, int y)
720 //  : BC_TextBox(x, y, xS(100), 1, thread->channels)
721 // {
722 //      this->thread = thread;
723 // }
724 // int SetVChannels::handle_event()
725 // {
726 //      thread->channels = atol(get_text());
727 //      return 1;
728 // }
729
730
731
732
733 ScaleSizeText::ScaleSizeText(int x, int y, SetFormatThread *thread, int *output)
734  : BC_TextBox(x, y, xS(100), 1, *output)
735 {
736         this->thread = thread;
737         this->output = output;
738 }
739 ScaleSizeText::~ScaleSizeText()
740 {
741 }
742 int ScaleSizeText::handle_event()
743 {
744         *output = atol(get_text());
745         *output /= 2;  *output *= 2;
746         if(*output <= 0) *output = 2;
747         if(*output > 10000) *output = 10000;
748         *output *= -1;
749         thread->update_window();
750         return 1;
751 }
752
753
754
755 ScaleRatioText::ScaleRatioText(int x,
756         int y,
757         SetFormatThread *thread,
758         float *output)
759  : BC_TextBox(x, y, xS(100), 1, *output)
760 {
761         this->thread = thread;
762         this->output = output;
763 }
764 ScaleRatioText::~ScaleRatioText()
765 {
766 }
767 int ScaleRatioText::handle_event()
768 {
769         *output = atof(get_text());
770         //if(*output <= 0) *output = 1;
771         if(*output > 10000) *output = 10000;
772         if(*output < -10000) *output = -10000;
773         *output *= -1;
774         thread->update_window();
775         return 1;
776 }
777
778
779 ScaleAspectAuto::ScaleAspectAuto(int x, int y, SetFormatThread *thread)
780  : BC_CheckBox(x, y, thread->auto_aspect, _("Auto"))
781 {
782         this->thread = thread;
783 }
784
785 ScaleAspectAuto::~ScaleAspectAuto()
786 {
787 }
788
789 int ScaleAspectAuto::handle_event()
790 {
791         thread->auto_aspect = get_value();
792         thread->update_aspect();
793         return 1;
794 }
795
796 ScaleAspectText::ScaleAspectText(int x, int y, SetFormatThread *thread, float *output)
797  : BC_TextBox(x, y, xS(70), 1, *output)
798 {
799         this->output = output;
800         this->thread = thread;
801 }
802 ScaleAspectText::~ScaleAspectText()
803 {
804 }
805
806 int ScaleAspectText::handle_event()
807 {
808         *output = atof(get_text());
809         return 1;
810 }
811
812
813 SetFormatApply::SetFormatApply(int x, int y, SetFormatThread *thread)
814  : BC_GenericButton(x, y, _("Apply"))
815 {
816         this->thread = thread;
817 }
818
819 int SetFormatApply::handle_event()
820 {
821         thread->apply_changes();
822         return 1;
823 }
824
825
826 FormatSwapExtents::FormatSwapExtents(MWindow *mwindow,
827         SetFormatThread *thread,
828         SetFormatWindow *gui,
829         int x,
830         int y)
831  : BC_Button(x, y, mwindow->theme->get_image_set("swap_extents"))
832 {
833         this->mwindow = mwindow;
834         this->thread = thread;
835         this->gui = gui;
836         set_tooltip(_("Swap dimensions"));
837 }
838
839 int FormatSwapExtents::handle_event()
840 {
841         int w = thread->dimension[0];
842         int h = thread->dimension[1];
843         thread->dimension[0] = -h;
844         gui->dimension[0]->update((int64_t)h);
845         gui->dimension[1]->update((int64_t)w);
846         thread->update_window();
847         thread->dimension[1] = -w;
848         thread->update_window();
849         return 1;
850 }
851