3 #include "cwindowgui.h"
7 #include "edlsession.h"
8 #include "formatpresets.h"
10 #include "levelwindow.h"
11 #include "levelwindowgui.h"
12 #include "mainerror.h"
16 #include "mwindowgui.h"
18 #include "preferences.h"
19 #include "rotateframe.h"
20 #include "setformat.h"
24 #include "vwindowgui.h"
28 SetFormat::SetFormat(MWindow *mwindow)
29 : BC_MenuItem(_("Format..."), "Shift-F", 'F')
32 this->mwindow = mwindow;
33 thread = new SetFormatThread(mwindow);
36 int SetFormat::handle_event()
38 if(!thread->running())
44 // window_lock has to be locked but window can't be locked until after
45 // it is known to exist, so we neglect window_lock for now
48 thread->window_lock->lock("SetFormat::handle_event");
49 thread->window->lock_window("SetFormat::handle_event");
50 thread->window->raise_window();
51 thread->window->unlock_window();
52 thread->window_lock->unlock();
58 SetFormatThread::SetFormatThread(MWindow *mwindow)
61 this->mwindow = mwindow;
62 window_lock = new Mutex("SetFormatThread::window_lock");
66 void SetFormatThread::run()
68 orig_dimension[0] = dimension[0] = mwindow->edl->session->output_w;
69 orig_dimension[1] = dimension[1] = mwindow->edl->session->output_h;
70 auto_aspect = mwindow->defaults->get("AUTOASPECT", 0);
72 ratio[0] = ratio[1] = 1;
74 new_settings = new EDL;
75 new_settings->create_objects();
76 new_settings->copy_session(mwindow->edl);
78 // This locks mwindow, so it must be done outside window_lock
79 int x = mwindow->gui->get_abs_cursor_x(1) - mwindow->theme->setformat_w / 2;
80 int y = mwindow->gui->get_abs_cursor_y(1) - mwindow->theme->setformat_h / 2;
82 window_lock->lock("SetFormatThread::run 1");
83 window = new SetFormatWindow(mwindow, this, x, y);
84 window->create_objects();
85 window_lock->unlock();
87 int result = window->run_window();
90 window_lock->lock("SetFormatThread::run 2");
93 window_lock->unlock();
101 mwindow->defaults->update("AUTOASPECT", auto_aspect);
105 void SetFormatThread::apply_changes()
107 double new_samplerate = new_settings->session->sample_rate;
108 double old_samplerate = mwindow->edl->session->sample_rate;
109 double new_framerate = new_settings->session->frame_rate;
110 double old_framerate = mwindow->edl->session->frame_rate;
111 int new_channels = new_settings->session->audio_channels;
112 CLAMP(new_channels, 1, MAXCHANNELS);
114 memcpy(&mwindow->preferences->channel_positions[MAXCHANNELS * (new_channels - 1)],
115 new_settings->session->achannel_positions,
116 sizeof(int) * MAXCHANNELS);
119 mwindow->edl->copy_session(new_settings, 1);
120 mwindow->edl->session->output_w = dimension[0];
121 mwindow->edl->session->output_h = dimension[1];
122 mwindow->edl->rechannel();
123 mwindow->edl->resample(old_samplerate, new_samplerate, TRACK_AUDIO);
124 mwindow->edl->resample(old_framerate, new_framerate, TRACK_VIDEO);
125 mwindow->save_backup();
126 mwindow->undo->update_undo(_("set format"), LOAD_ALL);
129 mwindow->restart_brender();
130 mwindow->gui->lock_window("SetFormatThread::apply_changes");
131 mwindow->gui->update(1,
138 mwindow->gui->unlock_window();
140 mwindow->cwindow->gui->lock_window("SetFormatThread::apply_changes");
141 mwindow->cwindow->gui->resize_event(mwindow->cwindow->gui->get_w(),
142 mwindow->cwindow->gui->get_h());
143 mwindow->cwindow->gui->meters->set_meters(new_channels, 1);
144 mwindow->cwindow->gui->slider->set_position();
145 mwindow->cwindow->gui->flush();
146 mwindow->cwindow->gui->unlock_window();
148 mwindow->vwindow->gui->lock_window("SetFormatThread::apply_changes");
149 mwindow->vwindow->gui->resize_event(mwindow->vwindow->gui->get_w(),
150 mwindow->vwindow->gui->get_h());
151 mwindow->vwindow->gui->meters->set_meters(new_channels, 1);
152 mwindow->vwindow->gui->flush();
153 mwindow->vwindow->gui->unlock_window();
155 mwindow->lwindow->gui->lock_window("SetFormatThread::apply_changes");
156 mwindow->lwindow->gui->panel->set_meters(new_channels, 1);
157 mwindow->lwindow->gui->flush();
158 mwindow->lwindow->gui->unlock_window();
161 if(((mwindow->edl->session->output_w % 4) ||
162 (mwindow->edl->session->output_h % 4)) &&
163 mwindow->edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
165 MainError::show_error(
166 _("This project's dimensions are not multiples of 4 so\n"
167 "it can't be rendered by OpenGL."));
172 mwindow->sync_parameters(CHANGE_ALL);
175 void SetFormatThread::update()
177 window->sample_rate->update(new_settings->session->sample_rate);
178 window->channels->update((int64_t)new_settings->session->audio_channels);
179 window->frame_rate->update((float)new_settings->session->frame_rate);
182 window->auto_aspect->update(0);
185 dimension[0] = new_settings->session->output_w;
186 window->dimension[0]->update((int64_t)dimension[0]);
187 dimension[1] = new_settings->session->output_h;
188 window->dimension[1]->update((int64_t)dimension[1]);
190 ratio[0] = (float)dimension[0] / orig_dimension[0];
191 window->ratio[0]->update(ratio[0]);
192 ratio[1] = (float)dimension[1] / orig_dimension[1];
193 window->ratio[1]->update(ratio[1]);
195 window->aspect_w->update(new_settings->session->aspect_w);
196 window->aspect_h->update(new_settings->session->aspect_h);
197 window->interlace_pulldown->update(new_settings->session->interlace_mode);
199 window->canvas->draw();
202 void SetFormatThread::update_window()
204 int i, result, modified_item, dimension_modified = 0, ratio_modified = 0;
206 for(i = 0, result = 0; i < 2 && !result; i++)
213 dimension_modified = 1;
226 if(dimension_modified)
227 ratio[modified_item] = (float)dimension[modified_item] / orig_dimension[modified_item];
229 if(ratio_modified && !constrain_ratio)
231 dimension[modified_item] = (int)(orig_dimension[modified_item] * ratio[modified_item]);
232 window->dimension[modified_item]->update((int64_t)dimension[modified_item]);
235 for(i = 0; i < 2; i++)
237 if(dimension_modified ||
238 (i != modified_item && ratio_modified))
240 if(constrain_ratio) ratio[i] = ratio[modified_item];
241 window->ratio[i]->update(ratio[i]);
245 (i != modified_item && dimension_modified))
249 dimension[i] = (int)(orig_dimension[i] * ratio[modified_item]);
250 window->dimension[i]->update((int64_t)dimension[i]);
259 void SetFormatThread::update_aspect()
263 char string[BCTEXTLEN];
264 MWindow::create_aspect_ratio(new_settings->session->aspect_w,
265 new_settings->session->aspect_h,
268 sprintf(string, "%.02f", new_settings->session->aspect_w);
269 window->aspect_w->update(string);
270 sprintf(string, "%.02f", new_settings->session->aspect_h);
271 window->aspect_h->update(string);
283 SetFormatWindow::SetFormatWindow(MWindow *mwindow,
284 SetFormatThread *thread,
287 : BC_Window(PROGRAM_NAME ": Set Format",
290 mwindow->theme->setformat_w,
291 mwindow->theme->setformat_h,
298 this->mwindow = mwindow;
299 this->thread = thread;
302 void SetFormatWindow::create_objects()
304 int x = 10, y = mwindow->theme->setformat_y1;
308 mwindow->theme->draw_setformat_bg(this);
312 presets = new SetFormatPresets(mwindow,
316 presets->create_objects();
320 y = mwindow->theme->setformat_y2;
322 add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
326 y = mwindow->theme->setformat_y3;
327 add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
331 y += mwindow->theme->setformat_margin;
332 add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
335 add_subwindow(sample_rate = new SetSampleRateTextBox(thread,
336 mwindow->theme->setformat_x2,
338 add_subwindow(new SampleRatePulldown(mwindow,
340 mwindow->theme->setformat_x2 + sample_rate->get_w(),
343 y += mwindow->theme->setformat_margin;
344 add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
347 add_subwindow(channels = new SetChannelsTextBox(thread,
348 mwindow->theme->setformat_x2,
350 add_subwindow(new BC_ITumbler(channels,
353 mwindow->theme->setformat_x2 + channels->get_w(),
356 y += mwindow->theme->setformat_margin;
357 add_subwindow(new BC_Title(mwindow->theme->setformat_x1,
359 _("Channel positions:")));
360 y += mwindow->theme->setformat_margin;
361 add_subwindow(canvas = new SetChannelsCanvas(mwindow,
363 mwindow->theme->setformat_channels_x,
364 mwindow->theme->setformat_channels_y,
365 mwindow->theme->setformat_channels_w,
366 mwindow->theme->setformat_channels_h));
377 y = mwindow->theme->setformat_y2;
378 add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
383 y = mwindow->theme->setformat_y3;
384 add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
387 add_subwindow(frame_rate = new SetFrameRateTextBox(thread,
388 mwindow->theme->setformat_x4,
390 add_subwindow(new FrameRatePulldown(mwindow,
392 mwindow->theme->setformat_x4 + frame_rate->get_w(),
395 y += mwindow->theme->setformat_margin;
396 add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
400 y += mwindow->theme->setformat_margin;
401 add_subwindow(title = new BC_Title(mwindow->theme->setformat_x3, y, _("Width:")));
402 add_subwindow(dimension[0] = new ScaleSizeText(mwindow->theme->setformat_x4,
405 &(thread->dimension[0])));
407 y += mwindow->theme->setformat_margin;
408 add_subwindow(new BC_Title(mwindow->theme->setformat_x3, y, _("Height:")));
409 add_subwindow(dimension[1] = new ScaleSizeText(mwindow->theme->setformat_x4,
412 &(thread->dimension[1])));
414 x = mwindow->theme->setformat_x4 + dimension[0]->get_w();
415 FrameSizePulldown *pulldown;
416 add_subwindow(pulldown = new FrameSizePulldown(mwindow,
420 y - mwindow->theme->setformat_margin));
422 add_subwindow(new FormatSwapExtents(mwindow,
425 x + pulldown->get_w() + 5,
426 y - mwindow->theme->setformat_margin));
428 y += mwindow->theme->setformat_margin;
429 add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
432 add_subwindow(ratio[0] = new ScaleRatioText(mwindow->theme->setformat_x4,
435 &(thread->ratio[0])));
437 y += mwindow->theme->setformat_margin;
438 add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
441 add_subwindow(ratio[1] = new ScaleRatioText(mwindow->theme->setformat_x4,
444 &(thread->ratio[1])));
446 y += mwindow->theme->setformat_margin;
447 add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
450 x = mwindow->theme->setformat_x4;
451 add_subwindow(color_model = new BC_TextBox(x,
456 x += color_model->get_w();
457 add_subwindow(new ColormodelPulldown(mwindow,
459 &thread->new_settings->session->color_model,
463 y += mwindow->theme->setformat_margin;
464 add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
466 _("Aspect ratio:")));
467 y += mwindow->theme->setformat_margin;
468 x = mwindow->theme->setformat_x3;
469 add_subwindow(aspect_w = new ScaleAspectText(x,
472 &(thread->new_settings->session->aspect_w)));
473 x += aspect_w->get_w() + 5;
474 add_subwindow(new BC_Title(x, y, _(":")));
476 add_subwindow(aspect_h = new ScaleAspectText(x,
479 &(thread->new_settings->session->aspect_h)));
480 x += aspect_h->get_w();
481 add_subwindow(new AspectPulldown(mwindow,
487 add_subwindow(auto_aspect = new ScaleAspectAuto(x, y, thread));
488 y += mwindow->theme->setformat_margin;
490 // --------------------
491 add_subwindow(new BC_Title(mwindow->theme->setformat_x3,
493 _("Interlace mode:")));
494 add_subwindow(textbox = new BC_TextBox(mwindow->theme->setformat_x4,
499 add_subwindow(interlace_pulldown = new InterlacemodePulldown(mwindow,
501 &(thread->new_settings->session->interlace_mode),
502 (ArrayList<BC_ListBoxItem*>*)&mwindow->interlace_project_modes,
503 mwindow->theme->setformat_x4 + textbox->get_w(),
505 y += mwindow->theme->setformat_margin;
509 BC_CancelTextButton *cancel;
510 add_subwindow(ok = new BC_OKTextButton(this));
511 add_subwindow(cancel = new BC_CancelTextButton(this));
512 add_subwindow(new SetFormatApply((ok->get_x() + cancel->get_x()) / 2,
519 char* SetFormatWindow::get_preset_text()
538 SetFormatPresets::SetFormatPresets(MWindow *mwindow,
539 SetFormatWindow *gui,
542 : FormatPresets(mwindow, 0, gui, x, y)
547 SetFormatPresets::~SetFormatPresets()
551 int SetFormatPresets::handle_event()
553 format_gui->thread->update();
557 EDL* SetFormatPresets::get_edl()
559 return format_gui->thread->new_settings;
576 SetSampleRateTextBox::SetSampleRateTextBox(SetFormatThread *thread, int x, int y)
577 : BC_TextBox(x, y, 100, 1, (int64_t)thread->new_settings->session->sample_rate)
579 this->thread = thread;
581 int SetSampleRateTextBox::handle_event()
583 thread->new_settings->session->sample_rate = CLIP(atol(get_text()), 1, 1000000);
587 SetChannelsTextBox::SetChannelsTextBox(SetFormatThread *thread, int x, int y)
588 : BC_TextBox(x, y, 100, 1, thread->new_settings->session->audio_channels)
590 this->thread = thread;
592 int SetChannelsTextBox::handle_event()
594 int new_channels = CLIP(atoi(get_text()), 1, MAXCHANNELS);
596 thread->new_settings->session->audio_channels = new_channels;
601 memcpy(thread->new_settings->session->achannel_positions,
602 &thread->mwindow->preferences->channel_positions[MAXCHANNELS * (new_channels - 1)],
603 sizeof(int) * MAXCHANNELS);
607 thread->window->canvas->draw();
612 SetChannelsCanvas::SetChannelsCanvas(MWindow *mwindow,
613 SetFormatThread *thread,
623 this->thread = thread;
624 this->mwindow = mwindow;
626 box_r = mwindow->theme->channel_position_data->get_w() / 2;
627 temp_picon = new VFrame(0,
628 mwindow->theme->channel_position_data->get_w(),
629 mwindow->theme->channel_position_data->get_h(),
630 mwindow->theme->channel_position_data->get_color_model());
631 rotater = new RotateFrame(mwindow->preferences->processors,
632 mwindow->theme->channel_position_data->get_w(),
633 mwindow->theme->channel_position_data->get_h());
635 SetChannelsCanvas::~SetChannelsCanvas()
641 int SetChannelsCanvas::draw(int angle)
644 int real_w = get_w() - box_r * 2;
645 int real_h = get_h() - box_r * 2;
649 draw_top_background(get_top_level(), 0, 0, get_w(), get_h());
650 // draw_vframe(mwindow->theme->channel_bg_data, 0, 0);
657 set_color(mwindow->theme->channel_position_color);
658 for(int i = 0; i < thread->new_settings->session->audio_channels; i++)
660 get_dimensions(thread->new_settings->session->achannel_positions[i],
665 double rotate_angle = thread->new_settings->session->achannel_positions[i];
666 rotate_angle = -rotate_angle;
667 while(rotate_angle < 0) rotate_angle += 360;
668 rotater->rotate(temp_picon,
669 mwindow->theme->channel_position_data,
673 BC_Pixmap temp_pixmap(this,
677 draw_pixmap(&temp_pixmap, x, y);
678 sprintf(string, "%d", i + 1);
679 draw_text(x + 2, y + box_r * 2 - 2, string);
684 sprintf(string, _("%d degrees"), angle);
685 draw_text(this->get_w() / 2 - 40, this->get_h() / 2, string);
692 int SetChannelsCanvas::get_dimensions(int channel_position,
699 int real_w = this->get_w() - box_r * 2 - MARGIN;
700 int real_h = this->get_h() - box_r * 2 - MARGIN;
701 float corrected_position = channel_position;
702 if(corrected_position < 0) corrected_position += 360;
703 Units::polar_to_xy((float)corrected_position, real_w / 2, x, y);
704 x += real_w / 2 + MARGIN / 2;
705 y += real_h / 2 + MARGIN / 2;
711 int SetChannelsCanvas::button_press_event()
713 if(!cursor_inside()) return 0;
714 // get active channel
716 i < thread->new_settings->session->audio_channels;
720 get_dimensions(thread->new_settings->session->achannel_positions[i],
725 if(get_cursor_x() > x && get_cursor_y() > y &&
726 get_cursor_x() < x + w && get_cursor_y() < y + h)
729 degree_offset = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
731 if(degree_offset >= 360) degree_offset -= 360;
732 degree_offset -= thread->new_settings->session->achannel_positions[i];
733 draw(thread->new_settings->session->achannel_positions[i]);
740 int SetChannelsCanvas::button_release_event()
742 if(active_channel >= 0)
751 int SetChannelsCanvas::cursor_motion_event()
753 if(active_channel >= 0)
755 // get degrees of new channel
757 new_d = (int)Units::xy_to_polar(get_cursor_x() - this->get_w() / 2, get_cursor_y() - this->get_h() / 2);
759 new_d -= degree_offset;
761 while(new_d >= 360) new_d -= 360;
762 while(new_d < 0) new_d += 360;
764 if(thread->new_settings->session->achannel_positions[active_channel] != new_d)
766 thread->new_settings->session->achannel_positions[active_channel] = new_d;
767 int new_channels = thread->new_settings->session->audio_channels;
768 memcpy(&thread->mwindow->preferences->channel_positions[MAXCHANNELS * (new_channels - 1)],
769 thread->new_settings->session->achannel_positions,
770 sizeof(int) * MAXCHANNELS);
771 draw(thread->new_settings->session->achannel_positions[active_channel]);
786 SetFrameRateTextBox::SetFrameRateTextBox(SetFormatThread *thread, int x, int y)
787 : BC_TextBox(x, y, 100, 1, (float)thread->new_settings->session->frame_rate)
789 this->thread = thread;
792 int SetFrameRateTextBox::handle_event()
794 thread->new_settings->session->frame_rate = Units::atoframerate(get_text());
800 // SetVChannels::SetVChannels(SetFormatThread *thread, int x, int y)
801 // : BC_TextBox(x, y, 100, 1, thread->channels)
803 // this->thread = thread;
805 // int SetVChannels::handle_event()
807 // thread->channels = atol(get_text());
814 ScaleSizeText::ScaleSizeText(int x, int y, SetFormatThread *thread, int *output)
815 : BC_TextBox(x, y, 100, 1, *output)
817 this->thread = thread;
818 this->output = output;
820 ScaleSizeText::~ScaleSizeText()
823 int ScaleSizeText::handle_event()
825 *output = atol(get_text());
828 if(*output <= 0) *output = 2;
829 if(*output > 10000) *output = 10000;
831 thread->update_window();
836 ScaleRatioText::ScaleRatioText(int x,
838 SetFormatThread *thread,
840 : BC_TextBox(x, y, 100, 1, *output)
842 this->thread = thread;
843 this->output = output;
845 ScaleRatioText::~ScaleRatioText()
848 int ScaleRatioText::handle_event()
850 *output = atof(get_text());
851 //if(*output <= 0) *output = 1;
852 if(*output > 10000) *output = 10000;
853 if(*output < -10000) *output = -10000;
855 thread->update_window();
861 ScaleAspectAuto::ScaleAspectAuto(int x, int y, SetFormatThread *thread)
862 : BC_CheckBox(x, y, thread->auto_aspect, _("Auto"))
864 this->thread = thread;
867 ScaleAspectAuto::~ScaleAspectAuto()
871 int ScaleAspectAuto::handle_event()
873 thread->auto_aspect = get_value();
874 thread->update_aspect();
877 ScaleAspectText::ScaleAspectText(int x, int y, SetFormatThread *thread, float *output)
878 : BC_TextBox(x, y, 70, 1, *output)
880 this->output = output;
881 this->thread = thread;
883 ScaleAspectText::~ScaleAspectText()
887 int ScaleAspectText::handle_event()
889 *output = atof(get_text());
898 SetFormatApply::SetFormatApply(int x, int y, SetFormatThread *thread)
899 : BC_GenericButton(x, y, _("Apply"))
901 this->thread = thread;
904 int SetFormatApply::handle_event()
906 thread->apply_changes();
922 FormatSwapExtents::FormatSwapExtents(MWindow *mwindow,
923 SetFormatThread *thread,
924 SetFormatWindow *gui,
927 : BC_Button(x, y, mwindow->theme->get_image_set("swap_extents"))
929 this->mwindow = mwindow;
930 this->thread = thread;
932 set_tooltip("Swap dimensions");
935 int FormatSwapExtents::handle_event()
937 int w = thread->dimension[0];
938 int h = thread->dimension[1];
939 thread->dimension[0] = -h;
940 gui->dimension[0]->update((int64_t)h);
941 gui->dimension[1]->update((int64_t)w);
942 thread->update_window();
943 thread->dimension[1] = -w;
944 thread->update_window();