Credit Andrew - improve in-tree documentation
[goodguy/cinelerra.git] / cinelerra / resizetrackthread.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 "asset.h"
23 #include "assetedit.h"
24 #include "edl.h"
25 #include "edlsession.h"
26 #include "language.h"
27 #include "mainerror.h"
28 #include "mainundo.h"
29 #include "mwindow.h"
30 #include "mwindowgui.h"
31 #include "new.h"
32 #include "resizetrackthread.h"
33 #include "theme.h"
34 #include "track.h"
35 #include "tracks.h"
36
37
38
39
40
41
42 ResizeVTrackThread::ResizeVTrackThread(MWindow *mwindow)
43  : Thread(1, 0, 0)
44 {
45         this->mwindow = mwindow;
46         window = 0;
47 }
48
49 ResizeVTrackThread::~ResizeVTrackThread()
50 {
51         if(window)
52         {
53                 window->lock_window();
54                 window->set_done(1);
55                 window->unlock_window();
56         }
57
58         Thread::join();
59 }
60
61 void ResizeVTrackThread::start_window(int w, int h, int w1, int h1)
62 {
63         if( window && running() ) {
64                 window->lock_window();
65                 window->raise_window();
66                 window->unlock_window();
67                 return;
68         }
69         this->w = w;    this->h = h;
70         this->w1 = w1;  this->h1 = h1;
71         w_scale = h_scale = 1;
72         start();
73 }
74
75
76 void ResizeVTrackThread::run()
77 {
78         window = new ResizeVTrackWindow(mwindow, this,
79                         mwindow->gui->get_abs_cursor_x(1),
80                         mwindow->gui->get_abs_cursor_y(1));
81         window->create_objects();
82         int result = window->run_window();
83
84         delete window;  window = 0;
85         if(!result) {
86                 update();
87         }
88
89         if(((w % 4) || (h % 4)) &&
90                 mwindow->edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
91         {
92                 MainError::show_error(
93                         _("This track's dimensions are not multiples of 4 so\n"
94                         "it can't be rendered by OpenGL."));
95         }
96 }
97
98
99
100
101 ResizeVTrackWindow::ResizeVTrackWindow(MWindow *mwindow,
102         ResizeVTrackThread *thread,
103         int x,
104         int y)
105  : BC_Window(_(PROGRAM_NAME ": Resize Track"),
106                                 x - 320 / 2, y - get_resources()->ok_images[0]->get_h() + 100 / 2,
107                                 400, get_resources()->ok_images[0]->get_h() + 100,
108                                 400, get_resources()->ok_images[0]->get_h() + 100,
109                                 0, 0, 1)
110 {
111         this->mwindow = mwindow;
112         this->thread = thread;
113 }
114
115 ResizeVTrackWindow::~ResizeVTrackWindow()
116 {
117 }
118
119 void ResizeVTrackWindow::create_objects()
120 {
121         lock_window("ResizeVTrackWindow::create_objects");
122         int x = 10, y = 10;
123         BC_Title *size_title = new BC_Title(x, y, _("Size:"));
124         add_subwindow(size_title);
125         int x1 = x + size_title->get_w();
126         int y1 = y + size_title->get_h() + 10;
127         BC_Title *scale_title = new BC_Title(x, y1, _("Scale:"));
128         add_subwindow(scale_title);
129         int x2 = x + scale_title->get_w();
130         if( x2 > x1 ) x1 = x2;
131         x1 += 10;
132         add_subwindow(w = new ResizeVTrackWidth(this, thread, x1, y));
133         x2 = x1 + w->get_w() + 5;
134         BC_Title *xy = new BC_Title(x2, y, _("x"));
135         add_subwindow(xy);
136         int x3 = x2 + xy->get_w() + 5;
137         add_subwindow(h = new ResizeVTrackHeight(this, thread, x3, y));
138         x = x3 + h->get_w() + 5;
139         FrameSizePulldown *pulldown;
140         add_subwindow(pulldown = new FrameSizePulldown(mwindow->theme, w, h, x, y));
141         x += pulldown->get_w() + 5;
142         add_subwindow(new ResizeVTrackSwap(this, thread, x, y));
143
144         add_subwindow(w_scale = new ResizeVTrackScaleW(this, thread, x1, y1));
145         add_subwindow(new BC_Title(x2, y1, _("x")));
146         add_subwindow(h_scale = new ResizeVTrackScaleH(this, thread, x3, y1));
147
148         add_subwindow(new BC_OKButton(this));
149         add_subwindow(new BC_CancelButton(this));
150
151         show_window();
152         flush();
153         unlock_window();
154 }
155
156 void ResizeVTrackWindow::update(int changed_scale,
157         int changed_size,
158         int changed_all)
159 {
160 //printf("ResizeVTrackWindow::update %d %d %d\n", changed_scale, changed_size, changed_all);
161         if(changed_scale || changed_all)
162         {
163                 thread->w = (int)(thread->w1 * thread->w_scale);
164                 w->update((int64_t)thread->w);
165                 thread->h = (int)(thread->h1 * thread->h_scale);
166                 h->update((int64_t)thread->h);
167         }
168         else
169         if(changed_size || changed_all)
170         {
171                 thread->w_scale = thread->w1 ? (double)thread->w / thread->w1 : 1.;
172                 w_scale->update((float)thread->w_scale);
173                 thread->h_scale = thread->h1 ? (double)thread->h / thread->h1 : 1.;
174                 h_scale->update((float)thread->h_scale);
175         }
176 }
177
178
179
180
181
182
183 ResizeVTrackSwap::ResizeVTrackSwap(ResizeVTrackWindow *gui,
184         ResizeVTrackThread *thread,
185         int x,
186         int y)
187  : BC_Button(x, y, thread->mwindow->theme->get_image_set("swap_extents"))
188 {
189         this->thread = thread;
190         this->gui = gui;
191         set_tooltip(_("Swap dimensions"));
192 }
193
194 int ResizeVTrackSwap::handle_event()
195 {
196         int w = thread->w;
197         int h = thread->h;
198         thread->w = h;
199         thread->h = w;
200         gui->w->update((int64_t)h);
201         gui->h->update((int64_t)w);
202         gui->update(0, 1, 0);
203         return 1;
204 }
205
206
207
208
209
210
211 ResizeVTrackWidth::ResizeVTrackWidth(ResizeVTrackWindow *gui,
212         ResizeVTrackThread *thread,
213         int x,
214         int y)
215  : BC_TextBox(x, y, 90, 1, thread->w)
216 {
217         this->gui = gui;
218         this->thread = thread;
219 }
220 int ResizeVTrackWidth::handle_event()
221 {
222         thread->w = atol(get_text());
223         gui->update(0, 1, 0);
224         return 1;
225 }
226
227 ResizeVTrackHeight::ResizeVTrackHeight(ResizeVTrackWindow *gui,
228         ResizeVTrackThread *thread,
229         int x,
230         int y)
231  : BC_TextBox(x, y, 90, 1, thread->h)
232 {
233         this->gui = gui;
234         this->thread = thread;
235 }
236 int ResizeVTrackHeight::handle_event()
237 {
238         thread->h = atol(get_text());
239         gui->update(0, 1, 0);
240         return 1;
241 }
242
243
244 ResizeVTrackScaleW::ResizeVTrackScaleW(ResizeVTrackWindow *gui,
245         ResizeVTrackThread *thread,
246         int x,
247         int y)
248  : BC_TextBox(x, y, 90, 1, (float)thread->w_scale)
249 {
250         this->gui = gui;
251         this->thread = thread;
252 }
253 int ResizeVTrackScaleW::handle_event()
254 {
255         thread->w_scale = atof(get_text());
256         gui->update(1, 0, 0);
257         return 1;
258 }
259
260 ResizeVTrackScaleH::ResizeVTrackScaleH(ResizeVTrackWindow *gui,
261         ResizeVTrackThread *thread,
262         int x,
263         int y)
264  : BC_TextBox(x, y, 90, 1, (float)thread->h_scale)
265 {
266         this->gui = gui;
267         this->thread = thread;
268 }
269 int ResizeVTrackScaleH::handle_event()
270 {
271         thread->h_scale = atof(get_text());
272         gui->update(1, 0, 0);
273         return 1;
274 }
275
276
277
278
279
280 ResizeTrackThread::ResizeTrackThread(MWindow *mwindow)
281  : ResizeVTrackThread(mwindow)
282 {
283 }
284
285 ResizeTrackThread::~ResizeTrackThread()
286 {
287 }
288
289
290 void ResizeTrackThread::start_window(Track *track)
291 {
292         this->track= track;
293         ResizeVTrackThread::start_window(track->track_w,
294                 track->track_h,
295                 track->track_w,
296                 track->track_h);
297 }
298
299 void ResizeTrackThread::update()
300 {
301         if( mwindow->edl->tracks->track_exists(track) )
302                 mwindow->resize_track(track, w, h);
303 }
304
305
306
307
308 ResizeAssetThread::ResizeAssetThread(AssetEditWindow *fwindow)
309  : ResizeVTrackThread(fwindow->mwindow)
310 {
311         this->fwindow = fwindow;
312 }
313
314 ResizeAssetThread::~ResizeAssetThread()
315 {
316 }
317
318 void ResizeAssetThread::start_window(Asset *asset)
319 {
320         this->asset = asset;
321         ResizeVTrackThread::start_window(asset->get_w(),
322                 asset->get_h(),
323                 asset->actual_width,
324                 asset->actual_height);
325 }
326
327 void ResizeAssetThread::update()
328 {
329         char string[BCTEXTLEN];
330         asset->width = w;
331         asset->height = h;
332         sprintf(string, "%d", asset->width);
333         fwindow->win_width->update(string);
334         sprintf(string, "%d", asset->height);
335         fwindow->win_height->update(string);
336 }
337
338 ResizeAssetButton::ResizeAssetButton(AssetEditWindow *fwindow, int x, int y)
339  : BC_GenericButton(x, y, _("Resize"))
340 {
341         resize_asset_thread = 0;
342         this->fwindow = fwindow;
343 }
344
345 ResizeAssetButton::~ResizeAssetButton()
346 {
347         delete resize_asset_thread;
348 }
349
350 int ResizeAssetButton::handle_event()
351 {
352         if( !resize_asset_thread )
353                 resize_asset_thread = new ResizeAssetThread(fwindow);
354         resize_asset_thread->start_window(fwindow->asset_edit->changed_params);
355         return 1;
356 }
357
358