Credit Andrew - fix vorbis audio which was scratchy and ensure aging plugin does...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / new.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 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 "browsebutton.h"
24 #include "clip.h"
25 #include "cplayback.h"
26 #include "cwindow.h"
27 #include "bchash.h"
28 #include "edl.h"
29 #include "edlsession.h"
30 #include "filesystem.h"
31 #include "filexml.h"
32 #include "interlacemodes.h"
33 #include "language.h"
34 #include "levelwindow.h"
35 #include "mainerror.h"
36 #include "mainundo.h"
37 #include "mainmenu.h"
38 #include "mutex.h"
39 #include "mwindow.h"
40 #include "mwindowgui.h"
41 #include "new.h"
42 #include "newpresets.h"
43 #include "mainsession.h"
44 #include "patchbay.h"
45 #include "preferences.h"
46 #include "theme.h"
47 #include "transportque.h"
48 #include "track.h"
49 #include "tracks.h"
50 #include "videowindow.h"
51 #include "vplayback.h"
52 #include "vwindow.h"
53
54
55 #include <string.h>
56
57
58 #define WIDTH xS(640)
59 // full height
60 #define HEIGHT0 yS(585)
61 // add tracks dialog
62 #define HEIGHT1 yS(240)
63 // offset for folder panel
64 #define HEIGHT2 yS(435)
65
66 New::New(MWindow *mwindow)
67 {
68         this->mwindow = mwindow;
69         new_edl = 0;
70         thread = 0;
71 }
72
73 New::~New()
74 {
75         delete thread;
76 }
77
78 int New::handle_event()
79 {
80         mwindow->gui->unlock_window();
81         mwindow->edl->save_defaults(mwindow->defaults);
82         create_new_edl();
83         thread->start();
84         mwindow->gui->lock_window("New::handle_event");
85
86         return 1;
87 }
88
89 void New::create_new_edl()
90 {
91         if( !new_edl ) {
92                 new_edl = new EDL;
93                 new_edl->create_objects();
94                 new_edl->load_defaults(mwindow->defaults);
95         }
96 }
97
98
99 int New::create_new_project(int load_mode)
100 {
101         mwindow->stop_playback(0);
102         mwindow->reset_caches(0);
103         mwindow->gui->lock_window();
104
105         memcpy(new_edl->session->achannel_positions,
106                 &mwindow->preferences->channel_positions[new_edl->session->audio_channels - 1],
107                 sizeof(new_edl->session->achannel_positions));
108         new_edl->session->boundaries();
109         new_edl->create_default_tracks();
110         if( load_mode == LOADMODE_NEW_TRACKS ) {
111                 Tracks *tracks =  mwindow->edl->tracks;
112                 int vindex = tracks->total_video_tracks();
113                 int aindex = tracks->total_audio_tracks();
114                 for( Track *track=new_edl->tracks->first; track; track=track->next ) {
115                         switch( track->data_type ) {
116                         case TRACK_AUDIO:
117                                 sprintf(track->title, _("Audio %d"), ++aindex);
118                                 break;
119                         case TRACK_VIDEO:
120                                 sprintf(track->title, _("Video %d"), ++vindex);
121                                 break;
122                         }
123                 }
124         }
125         mwindow->undo->update_undo_before();
126         mwindow->set_filename(new_edl->path);
127         ArrayList<EDL *>new_edls;
128         new_edls.append(new_edl);
129         mwindow->paste_edls(&new_edls, load_mode, 0,0,0,0,0,0);
130         new_edl->remove_user();
131         new_edl = 0;
132
133 // Load file sequence
134         mwindow->update_project(load_mode);
135         mwindow->session->changes_made = 0;
136         mwindow->undo->update_undo_after(load_mode == LOADMODE_REPLACE ?
137                 _("New Project") : _("Append to Project"), LOAD_ALL);
138         mwindow->gui->unlock_window();
139         return 0;
140 }
141
142 NewProject::NewProject(MWindow *mwindow)
143  : BC_MenuItem(_("New Project..."), "n", 'n'), New(mwindow)
144 {
145 }
146 NewProject::~NewProject()
147 {
148 }
149
150 void NewProject::create_objects()
151 {
152         thread = new NewThread(mwindow, this,
153                 _(PROGRAM_NAME ": New Project"), LOADMODE_REPLACE);
154 }
155
156 AppendTracks::AppendTracks(MWindow *mwindow)
157  : BC_MenuItem(_("Append to Project..."), "Shift-N", 'N'), New(mwindow)
158 {
159         set_shift(1);
160 }
161 AppendTracks::~AppendTracks()
162 {
163 }
164
165 void AppendTracks::create_objects()
166 {
167         thread = new NewThread(mwindow, this,
168                 _(PROGRAM_NAME ": Append to Project"), LOADMODE_NEW_TRACKS);
169 }
170
171
172 NewThread::NewThread(MWindow *mwindow, New *new_project,
173                 const char *title, int load_mode)
174  : BC_DialogThread()
175 {
176         this->mwindow = mwindow;
177         this->new_project = new_project;
178         this->title = title;
179         this->load_mode = load_mode;
180         nwindow = 0;
181 }
182
183 NewThread::~NewThread()
184 {
185         close_window();
186 }
187
188 BC_Window* NewThread::new_gui()
189 {
190         mwindow->edl->save_defaults(mwindow->defaults);
191         new_project->create_new_edl();
192         load_defaults();
193
194         mwindow->gui->lock_window("NewThread::new_gui");
195         int x = mwindow->gui->get_pop_cursor_x(0);
196         int y = mwindow->gui->get_pop_cursor_y(0);
197
198         nwindow = new NewWindow(mwindow, this, x, y);
199         nwindow->create_objects();
200         mwindow->gui->unlock_window();
201         return nwindow;
202 }
203
204 void NewThread::handle_done_event(int result)
205 {
206         if( !result && nwindow->folder && nwindow->name ) {
207                 const char *project_folder = nwindow->folder->get_text();
208                 const char *project_name = nwindow->name->get_text();
209                 if( project_folder[0] && project_name[0] ) {
210                         nwindow->recent_folder->add_item("PROJECT", project_folder);
211                         char project_path[BCTEXTLEN], *ep = project_path + sizeof(project_path);
212                         FileSystem fs;  fs.join_names(project_path, project_folder, project_name);
213                         char *bp = strrchr(project_path, '/');
214                         if( !bp ) bp = project_path;
215                         bp = strrchr(bp, '.');
216                         if( !bp ) bp = project_path + strlen(project_path);
217                         if( strcasecmp(bp,".xml") ) snprintf(bp, ep-bp, ".xml");
218                         fs.complete_path(project_path);
219                         EDL *new_edl = new_project->new_edl;
220                         bp = FileSystem::basepath(project_path);
221                         strcpy(new_edl->path, bp);  delete [] bp;
222                 }
223         }
224 }
225
226 void NewThread::handle_close_event(int result)
227 {
228         if( !new_project->new_edl ) return;
229
230         FileSystem fs;
231         char *path = new_project->new_edl->path;
232         char *bp = path;
233         while( !result ) {
234                 while( *bp == '/' ) ++bp;
235                 if( !(bp = strchr(bp, '/')) ) break;
236                 char dir_path[BCTEXTLEN];
237                 int len = bp - path;
238                 strncpy(dir_path, path, len);
239                 dir_path[len] = 0;
240                 if( fs.is_dir(dir_path) ) continue;
241                 if( fs.create_dir(dir_path) ) {
242                         eprintf(_("Cannot create and access project path:\n%s"),
243                                 dir_path);
244                         result = 1;
245                 }
246         }
247
248         if( !result ) {
249                 new_project->new_edl->save_defaults(mwindow->defaults);
250                 mwindow->defaults->save();
251                 new_project->create_new_project(load_mode);
252         }
253         else { // Aborted
254                 new_project->new_edl->Garbage::remove_user();
255                 new_project->new_edl = 0;
256         }
257 }
258
259 int NewThread::load_defaults()
260 {
261         auto_aspect = mwindow->defaults->get("AUTOASPECT", 0);
262         return 0;
263 }
264
265 int NewThread::save_defaults()
266 {
267         mwindow->defaults->update("AUTOASPECT", auto_aspect);
268         return 0;
269 }
270
271 int NewThread::update_aspect()
272 {
273         if( auto_aspect ) {
274                 char string[BCTEXTLEN];
275                 mwindow->create_aspect_ratio(new_project->new_edl->session->aspect_w,
276                         new_project->new_edl->session->aspect_h,
277                         new_project->new_edl->session->output_w,
278                         new_project->new_edl->session->output_h);
279                 sprintf(string, "%.02f", new_project->new_edl->session->aspect_w);
280                 if( nwindow->aspect_w_text ) nwindow->aspect_w_text->update(string);
281                 sprintf(string, "%.02f", new_project->new_edl->session->aspect_h);
282                 if( nwindow->aspect_h_text )nwindow->aspect_h_text->update(string);
283         }
284         return 0;
285 }
286
287
288 NewWindow::NewWindow(MWindow *mwindow, NewThread *new_thread, int x, int y)
289  : BC_Window(new_thread->title, x, y,
290                 WIDTH, new_thread->load_mode == LOADMODE_REPLACE ? HEIGHT0 : HEIGHT1,
291                 -1, -1, 0, 0, 1)
292 {
293         this->mwindow = mwindow;
294         this->new_thread = new_thread;
295         this->new_edl = new_thread->new_project->new_edl;
296         format_presets = 0;
297         atracks = 0;
298         achannels = 0;
299         sample_rate = 0;
300         vtracks = 0;
301         frame_rate = 0;
302         output_w_text = 0;
303         output_h_text = 0;
304         aspect_w_text = 0;
305         aspect_h_text = 0;
306         interlace_pulldown = 0;
307         color_model = 0;
308         folder = 0;
309         name = 0;
310         recent_folder = 0;
311 // *** CONTEXT_HELP ***
312         context_help_set_keyword("Project and Media Attributes");
313 }
314
315 NewWindow::~NewWindow()
316 {
317         lock_window("NewWindow::~NewWindow");
318         delete format_presets;
319         unlock_window();
320 }
321
322 void NewWindow::create_objects()
323 {
324         int xs10 = xS(10), xs20 = xS(20);
325         int ys5 = yS(5), ys10 = yS(10), ys20 = yS(20), ys30 = yS(30);
326         int xs2 = xS(2), xs64 = xS(64), xs115 = xS(115), xs150 = xS(150);
327         int ys40 = yS(40);
328         int x = xs10, y = ys10, x1, y1;
329         BC_TextBox *textbox;
330         BC_Title *title;
331
332         lock_window("NewWindow::create_objects");
333         mwindow->theme->draw_new_bg(this);
334
335         add_subwindow( new BC_Title(x, y, new_thread->load_mode == LOADMODE_REPLACE ?
336                         _("Parameters for the new project:") :
337                         _("Parameters for additional tracks:") ) );
338         y += ys20;
339
340         format_presets = new NewPresets(mwindow, this, x, y);
341         format_presets->create_objects();
342         x = format_presets->x;
343         y = format_presets->y;
344
345         y += ys40;
346         y1 = y;
347         add_subwindow(new BC_Title(x, y, _("Audio"), LARGEFONT));
348         y += ys30;
349
350         x1 = x;
351         add_subwindow(new BC_Title(x1, y, _("Tracks:")));
352         int xs100 = xS(100);
353         x1 += xs100;
354         add_subwindow(atracks = new NewATracks(this, "", x1, y));
355         x1 += atracks->get_w();
356         add_subwindow(new NewATracksTumbler(this, x1, y));
357         y += atracks->get_h() + ys5;
358
359         if( new_thread->load_mode == LOADMODE_REPLACE ) {
360                 x1 = x;
361                 add_subwindow(new BC_Title(x1, y, _("Channels:")));
362                 x1 += xs100;
363                 add_subwindow(achannels = new NewAChannels(this, "", x1, y));
364                 x1 += achannels->get_w();
365                 add_subwindow(new NewAChannelsTumbler(this, x1, y));
366                 y += achannels->get_h() + ys5;
367
368                 x1 = x;
369                 add_subwindow(new BC_Title(x1, y, _("Samplerate:")));
370                 x1 += xs100;
371                 add_subwindow(sample_rate = new NewSampleRate(this, "", x1, y));
372                 x1 += sample_rate->get_w();
373                 add_subwindow(new SampleRatePulldown(mwindow, sample_rate, x1, y));
374         }
375
376         x += xS(250);
377         y = y1;
378         add_subwindow(new BC_Title(x, y, _("Video"), LARGEFONT));
379         y += ys30;
380         x1 = x;
381         add_subwindow(new BC_Title(x1, y, _("Tracks:")));
382         x1 += xs115;
383         add_subwindow(vtracks = new NewVTracks(this, "", x1, y));
384         x1 += vtracks->get_w();
385         add_subwindow(new NewVTracksTumbler(this, x1, y));
386         y += vtracks->get_h() + ys5;
387
388         if( new_thread->load_mode == LOADMODE_REPLACE ) {
389 //              x1 = x;
390 //              add_subwindow(new BC_Title(x1, y, _("Channels:")));
391 //              x1 += xs100;
392 //              add_subwindow(vchannels = new NewVChannels(this, "", x1, y));
393 //              x1 += vchannels->get_w();
394 //              add_subwindow(new NewVChannelsTumbler(this, x1, y));
395 //              y += vchannels->get_h() + ys5;
396                 x1 = x;
397                 add_subwindow(new BC_Title(x1, y, _("Framerate:")));
398                 x1 += xs115;
399                 add_subwindow(frame_rate = new NewFrameRate(this, "", x1, y));
400                 x1 += frame_rate->get_w();
401                 add_subwindow(new FrameRatePulldown(mwindow, frame_rate, x1, y));
402                 y += frame_rate->get_h() + ys5;
403         }
404 //      x1 = x;
405 //      add_subwindow(new BC_Title(x1, y, _("Canvas size:")));
406 //      x1 += xs100;
407 //      add_subwindow(canvas_w_text = new NewTrackW(this, x1, y));
408 //      x1 += canvas_w_text->get_w() + xs2;
409 //      add_subwindow(new BC_Title(x1, y, "x"));
410 //      x1 += xs10;
411 //      add_subwindow(canvas_h_text = new NewTrackH(this, x1, y));
412 //      x1 += canvas_h_text->get_w();
413 //      add_subwindow(new FrameSizePulldown(mwindow,
414 //              canvas_w_text, canvas_h_text, x1, y));
415 //      x1 += xs100;
416 //      add_subwindow(new NewCloneToggle(mwindow, this, x1, y));
417 //      y += canvas_h_text->get_h() + ys5;
418
419         x1 = x;
420         add_subwindow(new BC_Title(x1, y, new_thread->load_mode == LOADMODE_REPLACE ?
421                         _("Canvas size:") : _("Track size:")));
422         x1 += xs115;
423         add_subwindow(output_w_text = new NewOutputW(this, x1, y));
424         x1 += output_w_text->get_w() + xs2;
425         add_subwindow(new BC_Title(x1, y, "x"));
426         x1 += xs10;
427         add_subwindow(output_h_text = new NewOutputH(this, x1, y));
428         x1 += output_h_text->get_w();
429         FrameSizePulldown *pulldown;
430         add_subwindow(pulldown = new FrameSizePulldown(mwindow->theme,
431                 output_w_text, output_h_text, x1, y));
432         x1 += pulldown->get_w() + xs10;
433         add_subwindow(new NewSwapExtents(mwindow, this, x1, y));
434         y += output_h_text->get_h() + ys5;
435
436         if( new_thread->load_mode == LOADMODE_REPLACE ) {
437                 x1 = x;
438                 add_subwindow(new BC_Title(x1, y, _("Aspect ratio:")));
439                 x1 += xs115;
440                 add_subwindow(aspect_w_text = new NewAspectW(this, "", x1, y));
441                 x1 += aspect_w_text->get_w() + xs2;
442                 add_subwindow(new BC_Title(x1, y, ":"));
443                 x1 += xs10;
444                 add_subwindow(aspect_h_text = new NewAspectH(this, "", x1, y));
445                 x1 += aspect_h_text->get_w();
446                 add_subwindow(new AspectPulldown(mwindow,
447                         aspect_w_text, aspect_h_text, x1, y));
448
449                 x1 = aspect_w_text->get_x();
450                 y += aspect_w_text->get_h() + ys5;
451                 add_subwindow(new NewAspectAuto(this, x1, y));
452                 y += ys40;
453                 add_subwindow(title = new BC_Title(x, y, _("Color model:")));
454                 x1 = x + title->get_w();
455                 y1 = y;  y += title->get_h() + ys10;
456                 add_subwindow(title = new BC_Title(x, y, _("Interlace mode:")));
457                 int x2 = x + title->get_w();
458                 int y2 = y;  y += title->get_h() + ys10;
459                 if( x1 < x2 ) x1 = x2;
460                 x1 += xs20;
461                 add_subwindow(textbox = new BC_TextBox(x1, y1, xs150, 1, ""));
462                 add_subwindow(color_model = new ColormodelPulldown(mwindow,
463                         textbox, &new_edl->session->color_model, x1+textbox->get_w(), y1));
464                 add_subwindow(textbox = new BC_TextBox(x1, y2, xs150, 1, ""));
465                 add_subwindow(interlace_pulldown = new InterlacemodePulldown(mwindow,
466                         textbox, &new_edl->session->interlace_mode,
467                         (ArrayList<BC_ListBoxItem*>*)&mwindow->interlace_project_modes,
468                         x1+textbox->get_w(), y2));
469
470                 x = xs20;  y = HEIGHT2;
471                 add_subwindow(title = new BC_Title(x, y, _("Create project folder in:")));
472                 x1 = x;  y += title->get_h() + ys5;
473                 add_subwindow(folder = new BC_TextBox(x1, y, get_w()-x1-xs64, 1, ""));
474                 x1 += folder->get_w() + xs10;
475                 add_subwindow(recent_folder = new BC_RecentList("FOLDER", mwindow->defaults, folder));
476                 recent_folder->load_items("PROJECT");
477                 x1 = recent_folder->get_x() + recent_folder->get_w();
478                 add_subwindow(new BrowseButton(mwindow->theme, this, folder, x1, y, "",
479                         _("Project Directory"), _("Project Directory Path:"), 1));
480                 y += folder->get_h() + ys10;  x1 = x;
481                 add_subwindow(title = new BC_Title(x1, y, _("Project Name:")));
482                 x1 += title->get_w() + xs10;
483                 add_subwindow(name = new BC_TextBox(x1, y, get_w()-x1-xs64, 1, ""));
484         }
485
486         add_subwindow(new BC_OKButton(this,
487                 mwindow->theme->get_image_set("new_ok_images")));
488         add_subwindow(new BC_CancelButton(this,
489                 mwindow->theme->get_image_set("new_cancel_images")));
490         flash();
491         update();
492         show_window();
493         unlock_window();
494 }
495
496 int NewWindow::update()
497 {
498         if( atracks ) atracks->update((int64_t)new_edl->session->audio_tracks);
499         if( achannels ) achannels->update((int64_t)new_edl->session->audio_channels);
500         if( sample_rate ) sample_rate->update((int64_t)new_edl->session->sample_rate);
501         if( vtracks ) vtracks->update((int64_t)new_edl->session->video_tracks);
502         if( frame_rate ) frame_rate->update((float)new_edl->session->frame_rate);
503         if( output_w_text ) output_w_text->update((int64_t)new_edl->session->output_w);
504         if( output_h_text ) output_h_text->update((int64_t)new_edl->session->output_h);
505         if( aspect_w_text ) aspect_w_text->update((float)new_edl->session->aspect_w);
506         if( aspect_h_text ) aspect_h_text->update((float)new_edl->session->aspect_h);
507         if( interlace_pulldown ) interlace_pulldown->update(new_edl->session->interlace_mode);
508         if( color_model ) color_model->update_value(new_edl->session->color_model);
509         return 0;
510 }
511
512
513 NewPresets::NewPresets(MWindow *mwindow, NewWindow *gui, int x, int y)
514  : FormatPresets(mwindow, gui, 0, x, y)
515 {
516 }
517
518 NewPresets::~NewPresets()
519 {
520 }
521
522 int NewPresets::handle_event()
523 {
524         new_gui->update();
525         return 1;
526 }
527
528 EDL* NewPresets::get_edl()
529 {
530         return new_gui->new_edl;
531 }
532
533
534 NewATracks::NewATracks(NewWindow *nwindow, const char *text, int x, int y)
535  : BC_TextBox(x, y, xS(90), 1, text)
536 {
537         this->nwindow = nwindow;
538 }
539
540 int NewATracks::handle_event()
541 {
542         nwindow->new_edl->session->audio_tracks = atol(get_text());
543         return 1;
544 }
545
546 NewATracksTumbler::NewATracksTumbler(NewWindow *nwindow, int x, int y)
547  : BC_Tumbler(x, y)
548 {
549         this->nwindow = nwindow;
550 }
551 int NewATracksTumbler::handle_up_event()
552 {
553         nwindow->new_edl->session->audio_tracks++;
554         nwindow->new_edl->boundaries();
555         nwindow->update();
556         return 1;
557 }
558 int NewATracksTumbler::handle_down_event()
559 {
560         nwindow->new_edl->session->audio_tracks--;
561         nwindow->new_edl->boundaries();
562         nwindow->update();
563         return 1;
564 }
565
566
567 NewAChannels::NewAChannels(NewWindow *nwindow, const char *text, int x, int y)
568  : BC_TextBox(x, y, xS(90), 1, text)
569 {
570         this->nwindow = nwindow;
571 }
572
573 int NewAChannels::handle_event()
574 {
575         nwindow->new_edl->session->audio_channels = atol(get_text());
576         return 1;
577 }
578
579
580 NewAChannelsTumbler::NewAChannelsTumbler(NewWindow *nwindow, int x, int y)
581  : BC_Tumbler(x, y)
582 {
583         this->nwindow = nwindow;
584 }
585 int NewAChannelsTumbler::handle_up_event()
586 {
587         nwindow->new_edl->session->audio_channels++;
588         nwindow->new_edl->boundaries();
589         nwindow->update();
590         return 1;
591 }
592 int NewAChannelsTumbler::handle_down_event()
593 {
594         nwindow->new_edl->session->audio_channels--;
595         nwindow->new_edl->boundaries();
596         nwindow->update();
597         return 1;
598 }
599
600
601 NewSampleRate::NewSampleRate(NewWindow *nwindow, const char *text, int x, int y)
602  : BC_TextBox(x, y, xS(90), 1, text)
603 {
604         this->nwindow = nwindow;
605 }
606
607 int NewSampleRate::handle_event()
608 {
609         nwindow->new_edl->session->sample_rate = atol(get_text());
610         return 1;
611 }
612
613
614 SampleRatePulldown::SampleRatePulldown(MWindow *mwindow, BC_TextBox *output, int x, int y)
615  : BC_ListBox(x, y, xS(100), xS(200), LISTBOX_TEXT,
616         &mwindow->theme->sample_rates, 0, 0, 1, 0, 1)
617 {
618         this->mwindow = mwindow;
619         this->output = output;
620 }
621 int SampleRatePulldown::handle_event()
622 {
623         char *text = get_selection(0, 0)->get_text();
624         output->update(text);
625         output->handle_event();
626         return 1;
627 }
628
629
630 NewVTracks::NewVTracks(NewWindow *nwindow, const char *text, int x, int y)
631  : BC_TextBox(x, y, xS(90), 1, text)
632 {
633         this->nwindow = nwindow;
634 }
635
636 int NewVTracks::handle_event()
637 {
638         nwindow->new_edl->session->video_tracks = atol(get_text());
639         return 1;
640 }
641
642
643 NewVTracksTumbler::NewVTracksTumbler(NewWindow *nwindow, int x, int y)
644  : BC_Tumbler(x, y)
645 {
646         this->nwindow = nwindow;
647 }
648 int NewVTracksTumbler::handle_up_event()
649 {
650         nwindow->new_edl->session->video_tracks++;
651         nwindow->new_edl->boundaries();
652         nwindow->update();
653         return 1;
654 }
655 int NewVTracksTumbler::handle_down_event()
656 {
657         nwindow->new_edl->session->video_tracks--;
658         nwindow->new_edl->boundaries();
659         nwindow->update();
660         return 1;
661 }
662
663
664 NewVChannels::NewVChannels(NewWindow *nwindow, const char *text, int x, int y)
665  : BC_TextBox(x, y, xS(90), 1, text)
666 {
667         this->nwindow = nwindow;
668 }
669
670 int NewVChannels::handle_event()
671 {
672         nwindow->new_edl->session->video_channels = atol(get_text());
673         return 1;
674 }
675
676
677 NewVChannelsTumbler::NewVChannelsTumbler(NewWindow *nwindow, int x, int y)
678  : BC_Tumbler(x, y)
679 {
680         this->nwindow = nwindow;
681 }
682 int NewVChannelsTumbler::handle_up_event()
683 {
684         nwindow->new_edl->session->video_channels++;
685         nwindow->new_edl->boundaries();
686         nwindow->update();
687         return 1;
688 }
689 int NewVChannelsTumbler::handle_down_event()
690 {
691         nwindow->new_edl->session->video_channels--;
692         nwindow->new_edl->boundaries();
693         nwindow->update();
694         return 1;
695 }
696
697
698 NewFrameRate::NewFrameRate(NewWindow *nwindow, const char *text, int x, int y)
699  : BC_TextBox(x, y, xS(90), 1, text)
700 {
701         this->nwindow = nwindow;
702 }
703
704 int NewFrameRate::handle_event()
705 {
706         nwindow->new_edl->session->frame_rate = Units::atoframerate(get_text());
707         return 1;
708 }
709
710
711 FrameRatePulldown::FrameRatePulldown(MWindow *mwindow,
712         BC_TextBox *output, int x, int y)
713  : BC_ListBox(x, y, xS(150), yS(250), LISTBOX_TEXT,
714         &mwindow->theme->frame_rates, 0, 0, 1, 0, 1)
715 {
716         this->mwindow = mwindow;
717         this->output = output;
718 // *** CONTEXT_HELP ***
719         context_help_set_keyword("Video In section");
720 }
721 int FrameRatePulldown::handle_event()
722 {
723         char *text = get_selection(0, 0)->get_text();
724         output->update(text);
725         output->handle_event();
726         return 1;
727 }
728
729 FrameSizePulldown::FrameSizePulldown(Theme *theme,
730                 BC_TextBox *output_w, BC_TextBox *output_h, int x, int y)
731  : BC_ListBox(x, y, xS(180), yS(250), LISTBOX_TEXT,
732         &theme->frame_sizes, 0, 0, 1, 0, 1)
733 {
734         this->theme = theme;
735         this->output_w = output_w;
736         this->output_h = output_h;
737 }
738
739 int FrameSizePulldown::handle_event()
740 {
741         char *text = get_selection(0, 0)->get_text();
742         char string[BCTEXTLEN];
743         int64_t w, h;
744         char *ptr;
745
746         strcpy(string, text);
747         ptr = strrchr(string, 'x');
748         if( ptr ) {
749                 ptr++;
750                 h = atol(ptr);
751
752                 *--ptr = 0;
753                 w = atol(string);
754                 output_w->update(w);
755                 output_h->update(h);
756                 output_w->handle_event();
757                 output_h->handle_event();
758         }
759         return 1;
760 }
761
762
763 NewOutputW::NewOutputW(NewWindow *nwindow, int x, int y)
764  : BC_TextBox(x, y, xS(70), 1, nwindow->new_edl->session->output_w)
765 {
766         this->nwindow = nwindow;
767 }
768 int NewOutputW::handle_event()
769 {
770         nwindow->new_edl->session->output_w = MAX(1,atol(get_text()));
771         nwindow->new_thread->update_aspect();
772         return 1;
773 }
774
775
776 NewOutputH::NewOutputH(NewWindow *nwindow, int x, int y)
777  : BC_TextBox(x, y, xS(70), 1, nwindow->new_edl->session->output_h)
778 {
779         this->nwindow = nwindow;
780 }
781 int NewOutputH::handle_event()
782 {
783         nwindow->new_edl->session->output_h = MAX(1, atol(get_text()));
784         nwindow->new_thread->update_aspect();
785         return 1;
786 }
787
788
789 NewAspectW::NewAspectW(NewWindow *nwindow, const char *text, int x, int y)
790  : BC_TextBox(x, y, xS(70), 1, text)
791 {
792         this->nwindow = nwindow;
793 }
794
795 int NewAspectW::handle_event()
796 {
797         nwindow->new_edl->session->aspect_w = atof(get_text());
798         return 1;
799 }
800
801
802 NewAspectH::NewAspectH(NewWindow *nwindow, const char *text, int x, int y)
803  : BC_TextBox(x, y, xS(70), 1, text)
804 {
805         this->nwindow = nwindow;
806 }
807
808 int NewAspectH::handle_event()
809 {
810         nwindow->new_edl->session->aspect_h = atof(get_text());
811         return 1;
812 }
813
814
815 AspectPulldown::AspectPulldown(MWindow *mwindow,
816                 BC_TextBox *output_w, BC_TextBox *output_h, int x, int y)
817  : BC_ListBox(x, y, xS(100), yS(200), LISTBOX_TEXT,
818         &mwindow->theme->aspect_ratios, 0, 0, 1, 0, 1)
819 {
820         this->mwindow = mwindow;
821         this->output_w = output_w;
822         this->output_h = output_h;
823 }
824
825 int AspectPulldown::handle_event()
826 {
827         char *text = get_selection(0, 0)->get_text();
828         char string[BCTEXTLEN];
829         float w, h;
830         char *ptr;
831
832         strcpy(string, text);
833         ptr = strrchr(string, ':');
834         if( ptr ) {
835                 ptr++;
836                 h = atof(ptr);
837
838                 *--ptr = 0;
839                 w = atof(string);
840                 output_w->update(w);
841                 output_h->update(h);
842                 output_w->handle_event();
843                 output_h->handle_event();
844         }
845         return 1;
846 }
847
848
849 ColormodelItem::ColormodelItem(const char *text, int value)
850  : BC_ListBoxItem(text)
851 {
852         this->value = value;
853 }
854
855 ColormodelPulldown::ColormodelPulldown(MWindow *mwindow,
856                 BC_TextBox *output_text, int *output_value, int x, int y)
857  : BC_ListBox(x, y, xS(200), yS(150), LISTBOX_TEXT,
858         (ArrayList<BC_ListBoxItem*>*)&mwindow->colormodels, 0, 0, 1, 0, 1)
859 {
860         this->mwindow = mwindow;
861         this->output_text = output_text;
862         this->output_value = output_value;
863         output_text->update(colormodel_to_text());
864 }
865
866 int ColormodelPulldown::handle_event()
867 {
868         output_text->update(get_selection(0, 0)->get_text());
869         *output_value = ((ColormodelItem*)get_selection(0, 0))->value;
870         return 1;
871 }
872
873 const char* ColormodelPulldown::colormodel_to_text()
874 {
875         for( int i=0; i<mwindow->colormodels.total; ++i )
876                 if( mwindow->colormodels.values[i]->value == *output_value )
877                         return mwindow->colormodels.values[i]->get_text();
878         return _("Unknown");
879 }
880
881 void ColormodelPulldown::update_value(int value)
882 {
883         *output_value = value;
884         output_text->update(colormodel_to_text());
885 }
886
887
888 InterlacemodeItem::InterlacemodeItem(const char *text, int value)
889  : BC_ListBoxItem(text)
890 {
891         this->value = value;
892 }
893
894 InterlacemodePulldown::InterlacemodePulldown(MWindow *mwindow,
895                 BC_TextBox *output_text,
896                 int *output_value,
897                 ArrayList<BC_ListBoxItem*> *data,
898                 int x,
899                 int y)
900  : BC_ListBox(x, y, xS(200), xS(150), LISTBOX_TEXT, data, 0, 0, 1, 0, 1)
901 {
902         this->mwindow = mwindow;
903         this->output_text = output_text;
904         this->output_value = output_value;
905         output_text->update(interlacemode_to_text());
906 }
907
908 int InterlacemodePulldown::handle_event()
909 {
910         output_text->update(get_selection(0, 0)->get_text());
911         *output_value = ((InterlacemodeItem*)get_selection(0, 0))->value;
912         return 1;
913 }
914
915 const char* InterlacemodePulldown::interlacemode_to_text()
916 {
917         ilacemode_to_text(this->string,*output_value);
918         return (this->string);
919 }
920
921 int InterlacemodePulldown::update(int interlace_mode)
922 {
923         *output_value = interlace_mode;
924         output_text->update(interlacemode_to_text());
925         return 1;
926 }
927
928
929 NewAspectAuto::NewAspectAuto(NewWindow *nwindow, int x, int y)
930  : BC_CheckBox(x, y, nwindow->new_thread->auto_aspect, _("Auto aspect ratio"))
931 {
932         this->nwindow = nwindow;
933 }
934 NewAspectAuto::~NewAspectAuto()
935 {
936 }
937 int NewAspectAuto::handle_event()
938 {
939         nwindow->new_thread->auto_aspect = get_value();
940         nwindow->new_thread->update_aspect();
941         return 1;
942 }
943
944
945 NewSwapExtents::NewSwapExtents(MWindow *mwindow, NewWindow *gui, int x, int y)
946  : BC_Button(x, y, mwindow->theme->get_image_set("swap_extents"))
947 {
948         this->mwindow = mwindow;
949         this->gui = gui;
950         set_tooltip(_("Swap dimensions"));
951 }
952
953 int NewSwapExtents::handle_event()
954 {
955         int w = gui->new_edl->session->output_w;
956         int h = gui->new_edl->session->output_h;
957         gui->new_edl->session->output_w = h;
958         gui->new_edl->session->output_h = w;
959         gui->output_w_text->update((int64_t)h);
960         gui->output_h_text->update((int64_t)w);
961         gui->new_thread->update_aspect();
962         return 1;
963 }
964