00001 #include "defaults.h"
00002 #include "mainundo.h"
00003 #include "mwindow.h"
00004 #include "scale.h"
00005 #include "mainsession.h"
00006 #include "tracks.h"
00007 #include "videowindow.h"
00008
00009 #include <libintl.h>
00010 #define _(String) gettext(String)
00011 #define gettext_noop(String) String
00012 #define N_(String) gettext_noop (String)
00013
00014 Scale::Scale(MWindow *mwindow)
00015 : BC_MenuItem(_("Resize..."))
00016 {
00017 this->mwindow = mwindow;
00018 thread = new ScaleThread(mwindow);
00019 }
00020
00021 Scale::~Scale()
00022 {
00023 delete thread;
00024 }
00025
00026 int Scale::handle_event()
00027 {
00028 thread->start();
00029 }
00030
00031 ScaleThread::ScaleThread(MWindow *mwindow)
00032 : Thread()
00033 {
00034 this->mwindow = mwindow;
00035 already_running = 0;
00036 }
00037
00038 ScaleThread::~ScaleThread() {}
00039
00040 void ScaleThread::run()
00041 {
00042 if(already_running) return;
00043 already_running = 1;
00044 constrain_ratio = mwindow->defaults->get("SCALECONSTRAIN", 0);
00045 scale_data = mwindow->defaults->get("SCALEDATA", 0);
00046 auto_aspect = mwindow->defaults->get("AUDIOASPECT", 0);
00047 offsets[0] = offsets[1] = offsets[2] = offsets[3] = 0;
00048
00049 orig_dimension[0] = dimension[0] = mwindow->session->track_w;
00050 orig_dimension[1] = dimension[1] = mwindow->session->track_h;
00051 orig_dimension[2] = dimension[2] = mwindow->session->output_w;
00052 orig_dimension[3] = dimension[3] = mwindow->session->output_h;
00053 ratio[0] = ratio[1] = ratio[2] = ratio[3] = 1;
00054 aspect_w = mwindow->session->aspect_w;
00055 aspect_h = mwindow->session->aspect_h;
00056
00057 window = new ScaleWindow(this);
00058 window->create_objects();
00059 int result = window->run_window();
00060 if(!result)
00061 {
00062 int dummy_offsets[4];
00063 dummy_offsets[0] = dummy_offsets[1] = dummy_offsets[2] = dummy_offsets[3] = 0;
00064
00065
00066
00067
00068
00069 mwindow->undo->update_undo_edits("Resize", 0);
00070 mwindow->tracks->scale_video(dimension, scale_data ? dummy_offsets : offsets, scale_data);
00071 mwindow->session->track_w = dimension[0];
00072 mwindow->session->track_h = dimension[1];
00073 mwindow->session->output_w = dimension[2];
00074 mwindow->session->output_h = dimension[3];
00075 mwindow->session->aspect_w = aspect_w;
00076 mwindow->session->aspect_h = aspect_h;
00077 mwindow->video_window->resize_window();
00078 mwindow->draw();
00079 mwindow->undo->update_undo_edits();
00080 mwindow->session->changes_made = 1;
00081 mwindow->defaults->update("ASPECTW", aspect_w);
00082 mwindow->defaults->update("ASPECTH", aspect_h);
00083 mwindow->defaults->update("AUTOASPECT", auto_aspect);
00084 }
00085 delete window;
00086
00087 mwindow->defaults->update("SCALECONSTRAIN", constrain_ratio);
00088 mwindow->defaults->update("SCALEDATA", scale_data);
00089 already_running = 0;
00090 }
00091
00092 int ScaleThread::update_window(int offset_updated)
00093 {
00094 int pair_start = 0;
00095 int i, result, modified_item, dimension_modified = 0, ratio_modified = 0;
00096
00097 for(i = 0, result = 0; i < 4 && !result; i++)
00098 {
00099 if(i == 2) pair_start = 2;
00100 if(dimension[i] < 0)
00101 {
00102 dimension[i] *= -1;
00103 result = 1;
00104 modified_item = i;
00105 dimension_modified = 1;
00106 }
00107 if(ratio[i] < 0)
00108 {
00109 ratio[i] *= -1;
00110 result = 1;
00111 modified_item = i;
00112 ratio_modified = 1;
00113 }
00114 }
00115
00116 if(result)
00117 {
00118 if(dimension_modified)
00119 ratio[modified_item] = (float)dimension[modified_item] / orig_dimension[modified_item];
00120
00121 if(ratio_modified && !constrain_ratio)
00122 {
00123 dimension[modified_item] = (int)(orig_dimension[modified_item] * ratio[modified_item]);
00124 window->dimension[modified_item]->update((long)dimension[modified_item]);
00125 }
00126
00127 for(i = pair_start; i < pair_start + 2 && constrain_ratio; i++)
00128 {
00129 if(dimension_modified ||
00130 (i != modified_item && ratio_modified))
00131 {
00132 ratio[i] = ratio[modified_item];
00133 window->ratio[i]->update(ratio[i]);
00134 }
00135
00136 if(ratio_modified ||
00137 (i != modified_item && dimension_modified))
00138 {
00139 dimension[i] = (int)(orig_dimension[i] * ratio[modified_item]);
00140 window->dimension[i]->update((long)dimension[i]);
00141 }
00142 }
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 update_aspect(window);
00157 return 0;
00158 }
00159
00160 int ScaleThread::update_aspect(ScaleWindow *window)
00161 {
00162 if(auto_aspect)
00163 {
00164 char string[1024];
00165 mwindow->create_aspect_ratio(aspect_w, aspect_h, dimension[2], dimension[3]);
00166 sprintf(string, "%.0f", aspect_w);
00167 window->aspect_w->update(string);
00168 sprintf(string, "%.0f", aspect_h);
00169 window->aspect_h->update(string);
00170 }
00171 }
00172
00173
00174
00175 ScaleWindow::ScaleWindow(ScaleThread *thread)
00176 : BC_Window(PROGRAM_NAME ": Scale", 370, 260, 0, 0)
00177 { this->thread = thread; }
00178
00179 ScaleWindow::~ScaleWindow()
00180 {
00181 }
00182
00183 int ScaleWindow::create_objects()
00184 {
00185 int x = 10, y = 10;
00186 add_subwindow(new BC_Title(x, y, _("New camera size:")));
00187 add_subwindow(new BC_Title(x + 200, y, _("New projector size:")));
00188 y += 30;
00189 add_subwindow(new BC_Title(x, y, _("Width:")));
00190 x += 70;
00191 add_subwindow(dimension[0] = new ScaleSizeText(x, y, thread, &(thread->dimension[0])));
00192 x += 110;
00193 add_subwindow(new BC_Title(x, y, _("Width:")));
00194 x += 70;
00195 add_subwindow(dimension[2] = new ScaleSizeText(x, y, thread, &(thread->dimension[2])));
00196
00197 y += 30;
00198 x = 10;
00199 add_subwindow(new BC_Title(x, y, _("Height:")));
00200 x += 70;
00201 add_subwindow(dimension[1] = new ScaleSizeText(x, y, thread, &(thread->dimension[1])));
00202 x += 110;
00203 add_subwindow(new BC_Title(x, y, _("Height:")));
00204 x += 70;
00205 add_subwindow(dimension[3] = new ScaleSizeText(x, y, thread, &(thread->dimension[3])));
00206
00207 y += 30;
00208 x = 10;
00209 add_subwindow(new BC_Title(x, y, _("W Ratio:")));
00210 x += 70;
00211 add_subwindow(ratio[0] = new ScaleRatioText(x, y, thread, &(thread->ratio[0])));
00212 x += 110;
00213 add_subwindow(new BC_Title(x, y, _("W Ratio:")));
00214 x += 70;
00215 add_subwindow(ratio[2] = new ScaleRatioText(x, y, thread, &(thread->ratio[2])));
00216
00217 y += 30;
00218 x = 10;
00219 add_subwindow(new BC_Title(x, y, _("H Ratio:")));
00220 x += 70;
00221 add_subwindow(ratio[1] = new ScaleRatioText(x, y, thread, &(thread->ratio[1])));
00222 x += 110;
00223 add_subwindow(new BC_Title(x, y, _("H Ratio:")));
00224 x += 70;
00225 add_subwindow(ratio[3] = new ScaleRatioText(x, y, thread, &(thread->ratio[3])));
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 x = 10;
00248 y += 30;
00249 add_subwindow(new BC_Title(x, y, _("Aspect ratio:")));
00250 x += 100;
00251 char string[1024];
00252 sprintf(string, "%.0f", thread->aspect_w);
00253 add_subwindow(aspect_w = new ScaleAspectW(x, y, thread, &(thread->aspect_w), string));
00254 x += 55;
00255 add_subwindow(new BC_Title(x, y, _(":")));
00256 x += 10;
00257 sprintf(string, "%.0f", thread->aspect_h);
00258 add_subwindow(aspect_h = new ScaleAspectH(x, y, thread, &(thread->aspect_h), string));
00259 x += 60;
00260 add_subwindow(new ScaleAspectAuto(x, y + 5, thread));
00261
00262 y += 30;
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 x = 10;
00282 add_subwindow(new ScaleConstrain(x, y, thread));
00283 x += 200;
00284 add_subwindow(new ScaleData(x, y, thread));
00285
00286 y += 30;
00287 x = 50;
00288 add_subwindow(new BC_OKButton(x, y));
00289 x += 200;
00290 add_subwindow(new BC_CancelButton(x, y));
00291 }
00292
00293 ScaleSizeText::ScaleSizeText(int x, int y, ScaleThread *thread, int *output)
00294 : BC_TextBox(x, y, 100, 1, *output)
00295 {
00296 this->thread = thread;
00297 this->output = output;
00298 }
00299 ScaleSizeText::~ScaleSizeText() {}
00300 int ScaleSizeText::handle_event()
00301 {
00302 *output = atol(get_text());
00303 *output /= 2;
00304 *output *= 2;
00305 if(*output <= 0) *output = 2;
00306 if(*output > 10000) *output = 10000;
00307 *output *= -1;
00308 thread->update_window();
00309 }
00310
00311 ScaleOffsetText::ScaleOffsetText(int x, int y, ScaleThread *thread, int *output)
00312 : BC_TextBox(x, y, 100, 1, *output)
00313 { this->thread = thread; this->output = output; }
00314 ScaleOffsetText::~ScaleOffsetText() {}
00315 int ScaleOffsetText::handle_event()
00316 {
00317 *output = atol(get_text());
00318
00319 if(*output > 10000) *output = 10000;
00320 if(*output < -10000) *output = -10000;
00321 thread->update_window(1);
00322 }
00323
00324 ScaleRatioText::ScaleRatioText(int x, int y, ScaleThread *thread, float *output)
00325 : BC_TextBox(x, y, 100, 1, *output)
00326 { this->thread = thread; this->output = output; }
00327 ScaleRatioText::~ScaleRatioText() {}
00328 int ScaleRatioText::handle_event()
00329 {
00330 *output = atof(get_text());
00331
00332 if(*output > 10000) *output = 10000;
00333 if(*output < -10000) *output = -10000;
00334 *output *= -1;
00335 thread->update_window();
00336 }
00337
00338
00339
00340
00341 ScaleConstrain::ScaleConstrain(int x, int y, ScaleThread *thread)
00342 : BC_CheckBox(x, y, thread->constrain_ratio, _("Constrain ratio"))
00343 { this->thread = thread; }
00344 ScaleConstrain::~ScaleConstrain() {}
00345 int ScaleConstrain::handle_event()
00346 {
00347 thread->constrain_ratio = get_value();
00348 }
00349
00350 ScaleData::ScaleData(int x, int y, ScaleThread *thread)
00351 : BC_CheckBox(x, y, thread->scale_data, _("Scale data"))
00352 { this->thread = thread; }
00353 ScaleData::~ScaleData() {}
00354 int ScaleData::handle_event()
00355 {
00356 thread->scale_data = get_value();
00357 thread->update_window();
00358 }
00359
00360
00361 ScaleAspectAuto::ScaleAspectAuto(int x, int y, ScaleThread *thread)
00362 : BC_CheckBox(x, y, thread->auto_aspect, _("Auto"))
00363 { this->thread = thread; }
00364
00365 ScaleAspectAuto::~ScaleAspectAuto()
00366 {
00367 }
00368
00369 int ScaleAspectAuto::handle_event()
00370 {
00371 thread->auto_aspect = get_value();
00372 thread->update_aspect(thread->window);
00373 }
00374
00375
00376
00377
00378 ScaleAspectW::ScaleAspectW(int x, int y, ScaleThread *thread, float *output, char *string)
00379 : BC_TextBox(x, y, 50, 1, string)
00380 {
00381 this->output = output;
00382 this->thread = thread;
00383 }
00384 ScaleAspectW::~ScaleAspectW()
00385 {
00386 }
00387
00388 int ScaleAspectW::handle_event()
00389 {
00390 *output = atof(get_text());
00391 }
00392
00393
00394 ScaleAspectH::ScaleAspectH(int x, int y, ScaleThread *thread, float *output, char *string)
00395 : BC_TextBox(x, y, 50, 1, string)
00396 {
00397 this->output = output;
00398 this->thread = thread;
00399 }
00400 ScaleAspectH::~ScaleAspectH()
00401 {
00402 }
00403
00404 int ScaleAspectH::handle_event()
00405 {
00406 *output = atof(get_text());
00407 }
00408
00409