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