r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / setformat.C
bloba711b128e88a68b3b028ad2ccd153c688a65c406
1 #include "clip.h"
2 #include "cwindow.h"
3 #include "cwindowgui.h"
4 #include "datatype.h"
5 #include "defaults.h"
6 #include "edl.h"
7 #include "edlsession.h"
8 #include "levelwindow.h"
9 #include "levelwindowgui.h"
10 #include "mainundo.h"
11 #include "mutex.h"
12 #include "mwindow.h"
13 #include "mwindowgui.h"
14 #include "new.h"
15 #include "rotateframe.h"
16 #include "setformat.h"
17 #include "theme.h"
18 #include "vframe.h"
19 #include "vwindow.h"
20 #include "vwindowgui.h"
22 #include <libintl.h>
23 #define _(String) gettext(String)
24 #define gettext_noop(String) String
25 #define N_(String) gettext_noop (String)
27 SetFormat::SetFormat(MWindow *mwindow)
28  : BC_MenuItem(_("Format..."))
30         this->mwindow = mwindow;
31         thread = new SetFormatThread(mwindow);
34 int SetFormat::handle_event()
36         if(!thread->running())
37         {
38                 thread->start();
39         }
40         else
41         {
42                 thread->window_lock->lock();
43                 if(thread->window) thread->window->raise_window();
44                 thread->window_lock->unlock();
45         }
46         return 1;
49 SetFormatThread::SetFormatThread(MWindow *mwindow)
50  : Thread()
52         this->mwindow = mwindow;
53         window_lock = new Mutex;
54         window = 0;
57 void SetFormatThread::run()
59         orig_dimension[0] = dimension[0] = mwindow->edl->session->output_w;
60         orig_dimension[1] = dimension[1] = mwindow->edl->session->output_h;
61         auto_aspect = mwindow->defaults->get("AUTOASPECT", 0);
62         constrain_ratio = 0;
63         ratio[0] = ratio[1] = 1;
65         new_settings = new EDL;
66         new_settings->create_objects();
67         new_settings->copy_session(mwindow->edl);
69         window_lock->lock();
70         window = new SetFormatWindow(mwindow, this);
71         window->create_objects();
72         window_lock->unlock();
74         int result = window->run_window();
77         window_lock->lock();
78         delete window;
79         window = 0;
80         window_lock->unlock();
83         if(!result)
84         {
85                 apply_changes();
86                 
87         }
88         
89         mwindow->defaults->update("AUTOASPECT", auto_aspect);
90         delete new_settings;
93 void SetFormatThread::apply_changes()
95         double new_samplerate = new_settings->session->sample_rate;
96         double old_samplerate = mwindow->edl->session->sample_rate;
97         double new_framerate = new_settings->session->frame_rate;
98         double old_framerate = mwindow->edl->session->frame_rate;
99         int new_channels = new_settings->session->audio_channels;
102         mwindow->undo->update_undo_before(_("set format"), LOAD_ALL);
103         mwindow->edl->copy_session(new_settings);
104         mwindow->edl->session->output_w = dimension[0];
105         mwindow->edl->session->output_h = dimension[1];
106         mwindow->edl->rechannel();
107         mwindow->edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
108         mwindow->edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
109         mwindow->save_backup();
110         mwindow->undo->update_undo_after();
112 // Update GUIs
113         mwindow->restart_brender();
114         mwindow->gui->lock_window();
115         mwindow->gui->update(1,
116                 1,
117                 1,
118                 1,
119                 1, 
120                 1,
121                 0);
122         mwindow->gui->unlock_window();
124         mwindow->cwindow->gui->lock_window();
125         mwindow->cwindow->gui->resize_event(mwindow->cwindow->gui->get_w(), 
126                 mwindow->cwindow->gui->get_h());
127         mwindow->cwindow->gui->meters->set_meters(new_channels, 1);
128         mwindow->cwindow->gui->slider->set_position();
129         mwindow->cwindow->gui->flush();
130         mwindow->cwindow->gui->unlock_window();
132         mwindow->vwindow->gui->lock_window();
133         mwindow->vwindow->gui->resize_event(mwindow->vwindow->gui->get_w(), 
134                 mwindow->vwindow->gui->get_h());
135         mwindow->vwindow->gui->meters->set_meters(new_channels, 1);
136         mwindow->vwindow->gui->flush();
137         mwindow->vwindow->gui->unlock_window();
139         mwindow->lwindow->gui->lock_window();
140         mwindow->lwindow->gui->panel->set_meters(new_channels, 1);
141         mwindow->lwindow->gui->flush();
142         mwindow->lwindow->gui->unlock_window();
144 // Flash frame
145         mwindow->sync_parameters(CHANGE_ALL);
148 void SetFormatThread::update_window()
150         int i, result, modified_item, dimension_modified = 0, ratio_modified = 0;
152         for(i = 0, result = 0; i < 2 && !result; i++)
153         {
154                 if(dimension[i] < 0)
155                 {
156                         dimension[i] *= -1;
157                         result = 1;
158                         modified_item = i;
159                         dimension_modified = 1;
160                 }
161                 if(ratio[i] < 0)
162                 {
163                         ratio[i] *= -1;
164                         result = 1;
165                         modified_item = i;
166                         ratio_modified = 1;
167                 }
168         }
170         if(result)
171         {
172                 if(dimension_modified)
173                         ratio[modified_item] = (float)dimension[modified_item] / orig_dimension[modified_item];
175                 if(ratio_modified && !constrain_ratio)
176                 {
177                         dimension[modified_item] = (int)(orig_dimension[modified_item] * ratio[modified_item]);
178                         window->dimension[modified_item]->update((int64_t)dimension[modified_item]);
179                 }
181                 for(i = 0; i < 2; i++)
182                 {
183                         if(dimension_modified ||
184                                 (i != modified_item && ratio_modified))
185                         {
186                                 if(constrain_ratio) ratio[i] = ratio[modified_item];
187                                 window->ratio[i]->update(ratio[i]);
188                         }
190                         if(ratio_modified ||
191                                 (i != modified_item && dimension_modified))
192                         {
193                                 if(constrain_ratio) 
194                                 {
195                                         dimension[i] = (int)(orig_dimension[i] * ratio[modified_item]);
196                                         window->dimension[i]->update((int64_t)dimension[i]);
197                                 }
198                         }
199                 }
200         }
202         update_aspect();
205 void SetFormatThread::update_aspect()
207         if(auto_aspect)
208         {
209                 char string[1024];
210                 MWindow::create_aspect_ratio(new_settings->session->aspect_w, 
211                         new_settings->session->aspect_h, 
212                         dimension[0], 
213                         dimension[1]);
214                 sprintf(string, "%.02f", new_settings->session->aspect_w);
215                 window->aspect_w->update(string);
216                 sprintf(string, "%.02f", new_settings->session->aspect_h);
217                 window->aspect_h->update(string);
218         }
229 SetFormatWindow::SetFormatWindow(MWindow *mwindow, SetFormatThread *thread)
230  : BC_Window(PROGRAM_NAME ": Set Format",
231         mwindow->gui->get_abs_cursor_x() - mwindow->theme->setformat_w / 2,
232         mwindow->gui->get_abs_cursor_y() - mwindow->theme->setformat_h / 2,
233         mwindow->theme->setformat_w,
234         mwindow->theme->setformat_h,
235         -1,
236         -1,
237         1,
238         0,
239         1)
241         this->mwindow = mwindow;
242         this->thread = thread;
245 void SetFormatWindow::create_objects()
247         int x, y = mwindow->theme->setformat_y1;
248         BC_TextBox *textbox;
250         mwindow->theme->draw_setformat_bg(this);
251         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, 
252                 y, 
253                 _("Audio"), 
254                 LARGEFONT));
255         y += mwindow->theme->setformat_margin;
256         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, 
257                 y,
258                 _("Samplerate:")));
260         y += mwindow->theme->setformat_margin;
261         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, 
262                 y,
263                 _("Samplerate:")));
264         add_subwindow(textbox = new SetSampleRateTextBox(thread, 
265                 mwindow->theme->setformat_x2, 
266                 y));
267         add_subwindow(new SampleRatePulldown(mwindow, 
268                 textbox, 
269                 mwindow->theme->setformat_x2 + textbox->get_w(), 
270                 y));
272         y += mwindow->theme->setformat_margin;
273         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, 
274                 y, 
275                 _("Channels:")));
276         add_subwindow(textbox = new SetChannelsTextBox(thread, 
277                 mwindow->theme->setformat_x2, 
278                 y));
279         add_subwindow(new BC_ITumbler(textbox, 
280                 1, 
281                 MAXCHANNELS, 
282                 mwindow->theme->setformat_x2 + textbox->get_w(), 
283                 y));
285         y += mwindow->theme->setformat_margin;
286         add_subwindow(new BC_Title(mwindow->theme->setformat_x1, 
287                 y, 
288                 _("Channel positions:")));
289         y += mwindow->theme->setformat_margin;
290         add_subwindow(canvas = new SetChannelsCanvas(mwindow, 
291                 thread, 
292                 mwindow->theme->setformat_channels_x, 
293                 mwindow->theme->setformat_channels_y, 
294                 mwindow->theme->setformat_channels_w, 
295                 mwindow->theme->setformat_channels_h));
296         canvas->draw();
306         y = mwindow->theme->setformat_y1;
307         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, 
308                 y, 
309                 _("Video"), 
310                 LARGEFONT));
312         y += mwindow->theme->setformat_margin;
313         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, 
314                 y, 
315                 _("Frame rate:")));
316         add_subwindow(textbox = new SetFrameRateTextBox(thread, 
317                 mwindow->theme->setformat_x4, 
318                 y));
319         add_subwindow(new FrameRatePulldown(mwindow, 
320                 textbox, 
321                 mwindow->theme->setformat_x4 + textbox->get_w(), 
322                 y));
324         y += mwindow->theme->setformat_margin;
325         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, 
326                 y, 
327                 _("Canvas size:")));
329         y += mwindow->theme->setformat_margin;
330         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, y, _("Width:")));
331         add_subwindow(dimension[0] = new ScaleSizeText(mwindow->theme->setformat_x4, 
332                 y, 
333                 thread, 
334                 &(thread->dimension[0])));
336         y += mwindow->theme->setformat_margin;
337         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, y, _("Height:")));
338         add_subwindow(dimension[1] = new ScaleSizeText(mwindow->theme->setformat_x4, 
339                 y, 
340                 thread, 
341                 &(thread->dimension[1])));
342         add_subwindow(new FrameSizePulldown(mwindow, 
343                 dimension[0], 
344                 dimension[1], 
345                 mwindow->theme->setformat_x4 + dimension[0]->get_w(), 
346                 y - mwindow->theme->setformat_margin));
348         y += mwindow->theme->setformat_margin;
349         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, 
350                 y, 
351                 _("W Ratio:")));
352         add_subwindow(ratio[0] = new ScaleRatioText(mwindow->theme->setformat_x4, 
353                 y, 
354                 thread, 
355                 &(thread->ratio[0])));
357         y += mwindow->theme->setformat_margin;
358         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, 
359                 y, 
360                 _("H Ratio:")));
361         add_subwindow(ratio[1] = new ScaleRatioText(mwindow->theme->setformat_x4, 
362                 y, 
363                 thread, 
364                 &(thread->ratio[1])));
366         y += mwindow->theme->setformat_margin;
367         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, 
368                 y, 
369                 _("Color model:")));
370         x = mwindow->theme->setformat_x4;
371         add_subwindow(textbox = new BC_TextBox(x, 
372                 y, 
373                 100, 
374                 1, 
375                 ""));
376         x += textbox->get_w();
377         add_subwindow(new ColormodelPulldown(mwindow, 
378                 textbox, 
379                 &thread->new_settings->session->color_model,
380                 x, 
381                 y));
383         y += mwindow->theme->setformat_margin;
384         add_subwindow(new BC_Title(mwindow->theme->setformat_x3, 
385                 y, 
386                 _("Aspect ratio:")));
387         y += mwindow->theme->setformat_margin;
388         x = mwindow->theme->setformat_x3;
389         add_subwindow(aspect_w = new ScaleAspectText(x, 
390                 y, 
391                 thread, 
392                 &(thread->new_settings->session->aspect_w)));
393         x += aspect_w->get_w() + 5;
394         add_subwindow(new BC_Title(x, y, _(":")));
395         x += 10;
396         add_subwindow(aspect_h = new ScaleAspectText(x, 
397                 y, 
398                 thread, 
399                 &(thread->new_settings->session->aspect_h)));
400         x += aspect_h->get_w();
401         add_subwindow(new AspectPulldown(mwindow, 
402                 aspect_w, 
403                 aspect_h, 
404                 x, 
405                 y));
406         x += 30;
407         add_subwindow(new ScaleAspectAuto(x, y, thread));
411         BC_OKButton *ok;
412         BC_CancelButton *cancel;
413         add_subwindow(ok = new BC_OKButton(this));
414         add_subwindow(cancel = new BC_CancelButton(this));
415         add_subwindow(new SetFormatApply((ok->get_x() + cancel->get_x()) / 2, 
416                 ok->get_y(), 
417                 thread));
418         flash();
419         show_window();
432 SetSampleRateTextBox::SetSampleRateTextBox(SetFormatThread *thread, int x, int y)
433  : BC_TextBox(x, y, 100, 1, (int64_t)thread->new_settings->session->sample_rate)
435         this->thread = thread;
437 int SetSampleRateTextBox::handle_event()
439         thread->new_settings->session->sample_rate = CLIP(atol(get_text()), 1, 1000000);
440         return 1;
443 SetChannelsTextBox::SetChannelsTextBox(SetFormatThread *thread, int x, int y)
444  : BC_TextBox(x, y, 100, 1, thread->new_settings->session->audio_channels)
446         this->thread = thread;
448 int SetChannelsTextBox::handle_event()
450         thread->new_settings->session->audio_channels = CLIP(atol(get_text()), 1, MAXCHANNELS - 1);
451         thread->window->canvas->draw();
452         return 1;
456 SetChannelsCanvas::SetChannelsCanvas(MWindow *mwindow, 
457         SetFormatThread *thread, 
458         int x, 
459         int y,
460         int w,
461         int h)
462  : BC_SubWindow(x, 
463         y, 
464         w,
465         h)
467 //printf("SetChannelsCanvas::SetChannelsCanvas 1\n");
468         this->thread = thread;
469         this->mwindow = mwindow;
470         active_channel = -1;
471 //printf("SetChannelsCanvas::SetChannelsCanvas 1\n");
472         box_r = mwindow->theme->channel_position_data->get_w() / 2;
473 //printf("SetChannelsCanvas::SetChannelsCanvas 1\n");
474         temp_picon = new VFrame(0, 
475                 mwindow->theme->channel_position_data->get_w(),
476                 mwindow->theme->channel_position_data->get_h(),
477                 mwindow->theme->channel_position_data->get_color_model());
478 //printf("SetChannelsCanvas::SetChannelsCanvas 1\n");
479         rotater = new RotateFrame(mwindow->edl->session->smp + 1,
480                 mwindow->theme->channel_position_data->get_w(),
481                 mwindow->theme->channel_position_data->get_h());
482 //printf("SetChannelsCanvas::SetChannelsCanvas 2\n");
484 SetChannelsCanvas::~SetChannelsCanvas()
486         delete temp_picon;
487         delete rotater;
490 int SetChannelsCanvas::draw(int angle)
492         set_color(RED);
493         int real_w = get_w() - box_r * 2;
494         int real_h = get_h() - box_r * 2;
495         int real_x = box_r;
496         int real_y = box_r;
498         draw_top_background(get_top_level(), 0, 0, get_w(), get_h());
499 //      draw_vframe(mwindow->theme->channel_bg_data, 0, 0);
504         int x, y, w, h;
505         char string[32];
506         set_color(mwindow->theme->channel_position_color);
507         for(int i = 0; i < thread->new_settings->session->audio_channels; i++)
508         {
509 //printf("SetChannelsCanvas::draw %d\n", thread->new_settings->session->achannel_positions[i]);
510                 get_dimensions(thread->new_settings->session->achannel_positions[i], 
511                         x, 
512                         y, 
513                         w, 
514                         h);
515                 double rotate_angle = thread->new_settings->session->achannel_positions[i];
516                 rotate_angle = -rotate_angle;
517                 while(rotate_angle < 0) rotate_angle += 360;
518                 rotater->rotate(temp_picon, 
519                         mwindow->theme->channel_position_data, 
520                         rotate_angle, 
521                         0);
523                 BC_Pixmap temp_pixmap(this, 
524                         temp_picon, 
525                         PIXMAP_ALPHA,
526                         0);
527                 draw_pixmap(&temp_pixmap, x, y);
528                 sprintf(string, "%d", i + 1);
529                 draw_text(x + 2, y + box_r * 2 - 2, string);
530         }
532         if(angle > -1)
533         {
534                 sprintf(string, _("%d degrees"), angle);
535                 draw_text(this->get_w() / 2 - 40, this->get_h() / 2, string);
536         }
538         flash();
539         return 0;
542 int SetChannelsCanvas::get_dimensions(int channel_position, 
543         int &x, 
544         int &y, 
545         int &w, 
546         int &h)
548 #define MARGIN 10
549         int real_w = this->get_w() - box_r * 2 - MARGIN;
550         int real_h = this->get_h() - box_r * 2 - MARGIN;
551         float corrected_position = channel_position;
552         if(corrected_position < 0) corrected_position += 360;
553         Units::polar_to_xy((float)corrected_position, real_w / 2, x, y);
554         x += real_w / 2 + MARGIN / 2;
555         y += real_h / 2 + MARGIN / 2;
556         w = box_r * 2;
557         h = box_r * 2;
558         return 0;
561 int SetChannelsCanvas::button_press_event()
563         if(!cursor_inside()) return 0;
564 // get active channel
565         for(int i = 0; 
566                 i < thread->new_settings->session->audio_channels; 
567                 i++)
568         {
569                 int x, y, w, h;
570                 get_dimensions(thread->new_settings->session->achannel_positions[i], 
571                         x, 
572                         y, 
573                         w, 
574                         h);
575                 if(get_cursor_x() > x && get_cursor_y() > y && 
576                         get_cursor_x() < x + w && get_cursor_y() < y + h)
577                 {
578                         active_channel = i;
579                         degree_offset = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
580                         degree_offset += 90;
581                         if(degree_offset >= 360) degree_offset -= 360;
582                         degree_offset -= thread->new_settings->session->achannel_positions[i];
583                         draw(thread->new_settings->session->achannel_positions[i]);
584                         return 1;
585                 }
586         }
587         return 0;
590 int SetChannelsCanvas::button_release_event()
592         if(active_channel >= 0)
593         {
594                 active_channel = -1;
595                 draw(-1);
596                 return 1;
597         }
598         return 0;
601 int SetChannelsCanvas::cursor_motion_event()
603         if(active_channel >= 0)
604         {
605 // get degrees of new channel
606                 int new_d;
607                 new_d = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
608                 new_d += 90;
609                 if(new_d >= 360) new_d -= 360;
610                 new_d -= degree_offset;
611                 if(new_d < 0) new_d += 360;
612                 if(thread->new_settings->session->achannel_positions[active_channel] != new_d)
613                 {
614                         thread->new_settings->session->achannel_positions[active_channel] = new_d;
615                         draw(thread->new_settings->session->achannel_positions[active_channel]);
616                 }
617                 return 1;
618         }
619         return 0;
630 SetFrameRateTextBox::SetFrameRateTextBox(SetFormatThread *thread, int x, int y)
631  : BC_TextBox(x, y, 100, 1, (float)thread->new_settings->session->frame_rate)
633         this->thread = thread;
636 int SetFrameRateTextBox::handle_event()
638         thread->new_settings->session->frame_rate = Units::atoframerate(get_text());
639         return 1;
643 // 
644 // SetVChannels::SetVChannels(SetFormatThread *thread, int x, int y)
645 //  : BC_TextBox(x, y, 100, 1, thread->channels)
646 // {
647 //      this->thread = thread;
648 // }
649 // int SetVChannels::handle_event()
650 // {
651 //      thread->channels = atol(get_text());
652 //      return 1;
653 // }
658 ScaleSizeText::ScaleSizeText(int x, int y, SetFormatThread *thread, int *output)
659  : BC_TextBox(x, y, 100, 1, *output)
661         this->thread = thread; 
662         this->output = output; 
664 ScaleSizeText::~ScaleSizeText()
667 int ScaleSizeText::handle_event()
669         *output = atol(get_text());
670         *output /= 2;
671         *output *= 2;
672         if(*output <= 0) *output = 2;
673         if(*output > 10000) *output = 10000;
674         *output *= -1;
675         thread->update_window();
680 ScaleRatioText::ScaleRatioText(int x, int y, SetFormatThread *thread, float *output)
681  : BC_TextBox(x, y, 100, 1, *output)
683         this->thread = thread; 
684         this->output = output; 
686 ScaleRatioText::~ScaleRatioText()
688 int ScaleRatioText::handle_event()
690         *output = atof(get_text());
691         //if(*output <= 0) *output = 1;
692         if(*output > 10000) *output = 10000;
693         if(*output < -10000) *output = -10000;
694         *output *= -1;
695         thread->update_window();
696         return 1;
701 ScaleAspectAuto::ScaleAspectAuto(int x, int y, SetFormatThread *thread)
702  : BC_CheckBox(x, y, thread->auto_aspect, _("Auto"))
704         this->thread = thread; 
707 ScaleAspectAuto::~ScaleAspectAuto()
711 int ScaleAspectAuto::handle_event()
713         thread->auto_aspect = get_value();
714         thread->update_aspect();
717 ScaleAspectText::ScaleAspectText(int x, int y, SetFormatThread *thread, float *output)
718  : BC_TextBox(x, y, 70, 1, *output)
720         this->output = output;
721         this->thread = thread;
723 ScaleAspectText::~ScaleAspectText()
727 int ScaleAspectText::handle_event()
729         *output = atof(get_text());
730         return 1;
736 SetFormatApply::SetFormatApply(int x, int y, SetFormatThread *thread)
737  : BC_GenericButton(x, y, _("Apply"))
739         this->thread = thread;
742 int SetFormatApply::handle_event()
744         thread->apply_changes();
745         return 1;