4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
26 #include "mainsession.h"
28 #include "videowindow.h"
31 #define _(String) gettext(String)
32 #define gettext_noop(String) String
33 #define N_(String) gettext_noop (String)
35 Scale::Scale(MWindow *mwindow)
36 : BC_MenuItem(_("Resize..."))
38 this->mwindow = mwindow;
39 thread = new ScaleThread(mwindow);
47 int Scale::handle_event()
53 ScaleThread::ScaleThread(MWindow *mwindow)
56 this->mwindow = mwindow;
60 ScaleThread::~ScaleThread() {}
62 void ScaleThread::run()
64 if(already_running) return;
66 constrain_ratio = mwindow->defaults->get("SCALECONSTRAIN", 0);
67 scale_data = mwindow->defaults->get("SCALEDATA", 0);
68 auto_aspect = mwindow->defaults->get("AUTOASPECT", 0);
69 offsets[0] = offsets[1] = offsets[2] = offsets[3] = 0;
71 orig_dimension[0] = dimension[0] = mwindow->session->track_w;
72 orig_dimension[1] = dimension[1] = mwindow->session->track_h;
73 orig_dimension[2] = dimension[2] = mwindow->session->output_w;
74 orig_dimension[3] = dimension[3] = mwindow->session->output_h;
75 ratio[0] = ratio[1] = ratio[2] = ratio[3] = 1;
76 aspect_w = mwindow->session->aspect_w;
77 aspect_h = mwindow->session->aspect_h;
79 window = new ScaleWindow(this);
80 window->create_objects();
81 int result = window->run_window();
85 dummy_offsets[0] = dummy_offsets[1] = dummy_offsets[2] = dummy_offsets[3] = 0;
86 // Fake the offsets if data is scaled.
89 //mwindow->stop_playback(1);
90 // save the before undo
91 mwindow->undo->update_undo_edits(_("Resize"), 0);
92 mwindow->tracks->scale_video(dimension, scale_data ? dummy_offsets : offsets, scale_data);
93 mwindow->session->track_w = dimension[0];
94 mwindow->session->track_h = dimension[1];
95 mwindow->session->output_w = dimension[2];
96 mwindow->session->output_h = dimension[3];
97 mwindow->session->aspect_w = aspect_w;
98 mwindow->session->aspect_h = aspect_h;
99 mwindow->video_window->resize_window();
101 mwindow->undo->update_undo_edits();
102 mwindow->session->changes_made = 1;
103 mwindow->defaults->update("ASPECTW", aspect_w);
104 mwindow->defaults->update("ASPECTH", aspect_h);
105 mwindow->defaults->update("AUTOASPECT", auto_aspect);
109 mwindow->defaults->update("SCALECONSTRAIN", constrain_ratio);
110 mwindow->defaults->update("SCALEDATA", scale_data);
114 int ScaleThread::update_window(int offset_updated)
117 int i, result, modified_item, dimension_modified = 0, ratio_modified = 0;
119 for(i = 0, result = 0; i < 4 && !result; i++)
121 if(i == 2) pair_start = 2;
127 dimension_modified = 1;
140 if(dimension_modified)
141 ratio[modified_item] = (float)dimension[modified_item] / orig_dimension[modified_item];
143 if(ratio_modified && !constrain_ratio)
145 dimension[modified_item] = (int)(orig_dimension[modified_item] * ratio[modified_item]);
146 window->dimension[modified_item]->update((long)dimension[modified_item]);
149 for(i = pair_start; i < pair_start + 2 && constrain_ratio; i++)
151 if(dimension_modified ||
152 (i != modified_item && ratio_modified))
154 ratio[i] = ratio[modified_item];
155 window->ratio[i]->update(ratio[i]);
159 (i != modified_item && dimension_modified))
161 dimension[i] = (int)(orig_dimension[i] * ratio[modified_item]);
162 window->dimension[i]->update((long)dimension[i]);
167 // window->position1->draw();
168 // window->position2->draw();
169 //printf("%d\n", offsets[0]);
170 // if(!offset_updated)
172 // window->offsets[0]->update(offsets[0]);
173 // window->offsets[1]->update(offsets[1]);
174 // window->offsets[2]->update(offsets[2]);
175 // window->offsets[3]->update(offsets[3]);
178 update_aspect(window);
182 int ScaleThread::update_aspect(ScaleWindow *window)
187 mwindow->create_aspect_ratio(aspect_w, aspect_h, dimension[2], dimension[3]);
188 sprintf(string, "%.0f", aspect_w);
189 window->aspect_w->update(string);
190 sprintf(string, "%.0f", aspect_h);
191 window->aspect_h->update(string);
198 ScaleWindow::ScaleWindow(ScaleThread *thread)
199 : BC_Window(_(PROGRAM_NAME ": Scale"), xS(370), yS(260), 0, 0)
200 { this->thread = thread; }
202 ScaleWindow::~ScaleWindow()
206 void ScaleWindow::create_objects()
208 int xs5 = xS(5), xs10 = xS(10), xs20 = xS(20), xs30 = xS(30), xs200 = xS(200);
209 int ys5 = yS(5), ys10 = yS(10), ys20 = yS(20), ys30 = yS(30);
210 lock_window("ScaleWindow::create_objects");
211 int x = xs10, y = ys10;
212 int x0 = x, x1 = x + xS(70), x2 = x1 = xS(110), x3 = x = xS(70);
213 add_subwindow(new BC_Title(x, y, _("New camera size:")));
214 add_subwindow(new BC_Title(x + xs200, y, _("New projector size:")));
216 add_subwindow(new BC_Title(x0, y, _("Width:")));
217 add_subwindow(dimension[0] = new ScaleSizeText(x1, y, thread, &(thread->dimension[0])));
218 add_subwindow(new BC_Title(x2, y, _("Width:")));
219 add_subwindow(dimension[2] = new ScaleSizeText(x3, y, thread, &(thread->dimension[2])));
222 add_subwindow(new BC_Title(x0, y, _("Height:")));
223 add_subwindow(dimension[1] = new ScaleSizeText(x1, y, thread, &(thread->dimension[1])));
224 add_subwindow(new BC_Title(x2, y, _("Height:")));
225 add_subwindow(dimension[3] = new ScaleSizeText(x3, y, thread, &(thread->dimension[3])));
228 add_subwindow(new BC_Title(x0, y, _("W Ratio:")));
229 add_subwindow(ratio[0] = new ScaleRatioText(x1, y, thread, &(thread->ratio[0])));
230 add_subwindow(new BC_Title(x2, y, _("W Ratio:")));
231 add_subwindow(ratio[2] = new ScaleRatioText(x3, y, thread, &(thread->ratio[2])));
234 add_subwindow(new BC_Title(x0, y, _("H Ratio:")));
235 add_subwindow(ratio[1] = new ScaleRatioText(x1, y, thread, &(thread->ratio[1])));
236 add_subwindow(new BC_Title(x2, y, _("H Ratio:")));
237 add_subwindow(ratio[3] = new ScaleRatioText(x3, y, thread, &(thread->ratio[3])));
240 // add_subwindow(new BC_Title(x0, y, "X Offset:"));
241 // add_subwindow(offsets[0] = new ScaleOffsetText(x1, y, thread, &(thread->offsets[0])));
242 // add_subwindow(new BC_Title(x2, y, "X Offset:"));
243 // add_subwindow(offsets[2] = new ScaleOffsetText(x3, y, thread, &(thread->offsets[2])));
246 // add_subwindow(new BC_Title(x0, y, "Y Offset:"));
247 // add_subwindow(offsets[1] = new ScaleOffsetText(x1, y, thread, &(thread->offsets[1])));
248 // add_subwindow(new BC_Title(x2, y, "Y Offset:"));
249 // add_subwindow(offsets[3] = new ScaleOffsetText(x3, y, thread, &(thread->offsets[3])));
252 add_subwindow(new BC_Title(x, y, _("Aspect ratio:")));
255 sprintf(string, "%.0f", thread->aspect_w);
256 add_subwindow(aspect_w = new ScaleAspectW(x, y, thread, &(thread->aspect_w), string));
258 add_subwindow(new BC_Title(x, y, ":"));
260 sprintf(string, "%.0f", thread->aspect_h);
261 add_subwindow(aspect_h = new ScaleAspectH(x, y, thread, &(thread->aspect_h), string));
263 add_subwindow(new ScaleAspectAuto(x, y + 5, thread));
267 // add_subwindow(new BC_Title(x, y, _("Camera position:")));
269 // add_subwindow(new BC_Title(x, y, _("Projector position:")));
271 // ScalePosition *position;
274 // add_subwindow(position1 = new ScalePosition(x, y, thread, this,
275 // &(thread->orig_dimension[0]), &(thread->dimension[0]), &(thread->offsets[0])));
276 // position1->draw();
279 // add_subwindow(position2 = new ScalePosition(x, y, thread, this,
280 // &(thread->orig_dimension[2]), &(thread->dimension[2]), &(thread->offsets[2])));
281 // position2->draw();
285 add_subwindow(new ScaleConstrain(x, y, thread));
287 add_subwindow(new ScaleData(x, y, thread));
291 add_subwindow(new BC_OKButton(x, y));
293 add_subwindow(new BC_CancelButton(x, y));
297 ScaleSizeText::ScaleSizeText(int x, int y, ScaleThread *thread, int *output)
298 : BC_TextBox(x, y, xS(100), 1, *output)
300 this->thread = thread;
301 this->output = output;
303 ScaleSizeText::~ScaleSizeText() {}
304 int ScaleSizeText::handle_event()
306 *output = atol(get_text());
307 *output /= 2; *output *= 2;
308 if(*output <= 0) *output = 2;
309 if(*output > 10000) *output = 10000;
311 thread->update_window();
315 ScaleOffsetText::ScaleOffsetText(int x, int y, ScaleThread *thread, int *output)
316 : BC_TextBox(x, y, xs(100), 1, *output)
317 { this->thread = thread; this->output = output; }
318 ScaleOffsetText::~ScaleOffsetText() {}
319 int ScaleOffsetText::handle_event()
321 *output = atol(get_text());
322 //if(*output <= 0) *output = 0;
323 if(*output > 10000) *output = 10000;
324 if(*output < -10000) *output = -10000;
325 thread->update_window(1);
329 ScaleRatioText::ScaleRatioText(int x, int y, ScaleThread *thread, float *output)
330 : BC_TextBox(x, y, xS(100), 1, *output)
331 { this->thread = thread; this->output = output; }
332 ScaleRatioText::~ScaleRatioText() {}
333 int ScaleRatioText::handle_event()
335 *output = atof(get_text());
336 //if(*output <= 0) *output = 1;
337 if(*output > 10000) *output = 10000;
338 if(*output < -10000) *output = -10000;
340 thread->update_window();
347 ScaleConstrain::ScaleConstrain(int x, int y, ScaleThread *thread)
348 : BC_CheckBox(x, y, thread->constrain_ratio, _("Constrain ratio"))
349 { this->thread = thread; }
350 ScaleConstrain::~ScaleConstrain() {}
351 int ScaleConstrain::handle_event()
353 thread->constrain_ratio = get_value();
357 ScaleData::ScaleData(int x, int y, ScaleThread *thread)
358 : BC_CheckBox(x, y, thread->scale_data, _("Scale data"))
359 { this->thread = thread; }
360 ScaleData::~ScaleData() {}
361 int ScaleData::handle_event()
363 thread->scale_data = get_value();
364 thread->update_window();
369 ScaleAspectAuto::ScaleAspectAuto(int x, int y, ScaleThread *thread)
370 : BC_CheckBox(x, y, thread->auto_aspect, _("Auto"))
371 { this->thread = thread; }
373 ScaleAspectAuto::~ScaleAspectAuto()
377 int ScaleAspectAuto::handle_event()
379 thread->auto_aspect = get_value();
380 thread->update_aspect(thread->window);
387 ScaleAspectW::ScaleAspectW(int x, int y, ScaleThread *thread, float *output, char *string)
388 : BC_TextBox(x, y, xS(50), 1, string)
390 this->output = output;
391 this->thread = thread;
393 ScaleAspectW::~ScaleAspectW()
397 int ScaleAspectW::handle_event()
399 *output = atof(get_text());
404 ScaleAspectH::ScaleAspectH(int x, int y, ScaleThread *thread, float *output, char *string)
405 : BC_TextBox(x, y, xS(50), 1, string)
407 this->output = output;
408 this->thread = thread;
410 ScaleAspectH::~ScaleAspectH()
414 int ScaleAspectH::handle_event()
416 *output = atof(get_text());