add haupauge-1657 dual usb capture support, add deinterlace to recordmonitor, asset...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / transitionpopup.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 "bcdisplayinfo.h"
23 #include "clip.h"
24 #include "edit.h"
25 #include "edl.h"
26 #include "edlsession.h"
27 #include "language.h"
28 #include "mwindow.h"
29 #include "mwindowgui.h"
30 #include "plugin.h"
31 #include "transition.h"
32 #include "track.h"
33 #include "tracks.h"
34 #include "transitionpopup.h"
35
36
37 TransitionLengthThread::TransitionLengthThread(MWindow *mwindow)
38  : BC_DialogThread()
39 {
40         this->mwindow = mwindow;
41 }
42
43 TransitionLengthThread::~TransitionLengthThread()
44 {
45         close_window();
46 }
47
48 void TransitionLengthThread::start(Transition *transition, double length)
49 {
50         this->transition = transition;
51         this->orig_length = length;
52         this->new_length = length;
53         BC_DialogThread::start();
54 }
55
56 #define TLW_W xS(300)
57 #define TLW_H yS(100)
58
59 BC_Window* TransitionLengthThread::new_gui()
60 {
61         BC_DisplayInfo display_info;
62         int x = display_info.get_abs_cursor_x() - TLW_W / 2;
63         int y = display_info.get_abs_cursor_y() - TLW_H / 2;
64         TransitionLengthDialog *gui = new TransitionLengthDialog(mwindow, this, x, y);
65         gui->create_objects();
66         return gui;
67 }
68
69 void TransitionLengthThread::handle_close_event(int result)
70 {
71         if( !result ) {
72                 if( transition )
73                         mwindow->set_transition_length(transition, new_length);
74                 else
75                         mwindow->set_transition_length(new_length);
76         }
77         else
78                 update(orig_length);
79 }
80
81 int TransitionLengthThread::update(double length)
82 {
83         if( !EQUIV(this->new_length, length) ) {
84                 this->new_length = length;
85                 if( transition ) {
86                         transition->length = transition->track->to_units(length, 1);
87                         mwindow->sync_parameters(CHANGE_EDL);
88                         mwindow->gui->lock_window();
89                         mwindow->gui->draw_overlays(1);
90                         mwindow->gui->unlock_window();
91                 }
92         }
93         return 1;
94 }
95
96
97 TransitionUnitsItem::TransitionUnitsItem(TransitionUnitsPopup *popup,
98                 const char *text, int id)
99  : BC_MenuItem(text)
100 {
101         this->popup = popup;
102         this->id = id;
103 }
104
105 TransitionUnitsItem::~TransitionUnitsItem()
106 {
107 }
108
109 int TransitionUnitsItem::handle_event()
110 {
111         TransitionUnitsPopup *units_popup = (TransitionUnitsPopup *)get_popup_menu();
112         TransitionLengthDialog *gui = units_popup->gui;
113         TransitionLengthText *length_text = gui->text;
114         EDLSession *session = gui->mwindow->edl->session;
115         double length = gui->thread->new_length;
116         char text[BCSTRLEN];
117         units_popup->units = id;
118         Units::totext(text, length, units_popup->units, session->sample_rate,
119                         session->frame_rate, session->frames_per_foot);
120         length_text->update(text);
121         units_popup->set_text(get_text());
122         return 1;
123 }
124
125 TransitionUnitsPopup::TransitionUnitsPopup(TransitionLengthDialog *gui, int x, int y)
126  : BC_PopupMenu(x, y, xS(120), "", 1)
127 {
128         this->gui = gui;
129         units = TIME_SECONDS;
130 }
131
132 TransitionUnitsPopup::~TransitionUnitsPopup()
133 {
134 }
135
136 void TransitionUnitsPopup::create_objects()
137 {
138         TransitionUnitsItem *units_item;
139         add_item(units_item = new TransitionUnitsItem(this, _("Seconds"), TIME_SECONDS));
140         add_item(new TransitionUnitsItem(this, _("Frames"), TIME_FRAMES));
141         add_item(new TransitionUnitsItem(this, _("Samples"), TIME_SAMPLES));
142         add_item(new TransitionUnitsItem(this, _("H:M:S.xxx"), TIME_HMS));
143         add_item(new TransitionUnitsItem(this, _("H:M:S:frm"), TIME_HMSF));
144         set_text(units_item->get_text());
145 }
146
147
148 TransitionLengthDialog::TransitionLengthDialog(MWindow *mwindow,
149         TransitionLengthThread *thread, int x, int y)
150  : BC_Window(_(PROGRAM_NAME ": Transition length"), x, y,
151                 TLW_W, TLW_H, -1, -1, 0, 0, 1)
152 {
153         this->mwindow = mwindow;
154         this->thread = thread;
155 }
156
157 TransitionLengthDialog::~TransitionLengthDialog()
158 {
159 }
160
161
162 void TransitionLengthDialog::create_objects()
163 {
164         lock_window("TransitionLengthDialog::create_objects");
165         add_subwindow(units_popup = new TransitionUnitsPopup(this, xS(10), yS(10)));
166         units_popup->create_objects();
167         text = new TransitionLengthText(mwindow, this, xS(160), yS(10));
168         text->create_objects();
169         text->set_precision(3);
170         text->set_increment(0.1);
171         add_subwindow(new BC_OKButton(this));
172         add_subwindow(new BC_CancelButton(this));
173         show_window();
174         unlock_window();
175 }
176
177 int TransitionLengthDialog::close_event()
178 {
179         set_done(0);
180         return 1;
181 }
182
183
184 TransitionLengthText::TransitionLengthText(MWindow *mwindow,
185         TransitionLengthDialog *gui, int x, int y)
186  : BC_TumbleTextBox(gui, (float)gui->thread->new_length,
187                 0.f, 100.f, x, y, xS(100))
188 {
189         this->mwindow = mwindow;
190         this->gui = gui;
191 }
192
193 int TransitionLengthText::handle_event()
194 {
195         const char *text = get_text();
196         int units = gui->units_popup->units;
197         EDLSession *session = gui->mwindow->edl->session;
198         double result = Units::text_to_seconds(text, session->sample_rate,
199                 units, session->frame_rate, session->frames_per_foot);
200         return gui->thread->update(result);
201 }
202
203 int TransitionLengthText::handle_up_down(int dir)
204 {
205         double delta = 0;
206         int units = gui->units_popup->units;
207         EDLSession *session = gui->mwindow->edl->session;
208         switch( units ) {
209         case TIME_SECONDS:
210         case TIME_HMS:
211                 delta = 0.1;
212                 break;
213         case TIME_HMSF:
214         case TIME_FRAMES:
215                 delta = session->frame_rate > 0 ? 1./session->frame_rate : 0;
216                 break;
217         case TIME_SAMPLES:
218                 delta = session->sample_rate > 0 ? 1./session->sample_rate : 0;
219                 break;
220         }
221         double length = gui->thread->new_length + delta * dir;
222         char text[BCSTRLEN];
223         Units::totext(text, length, units,
224                 session->sample_rate, session->frame_rate,
225                 session->frames_per_foot);
226         update(text);
227         return gui->thread->update(length);
228 }
229
230 int TransitionLengthText::handle_up_event()
231 {
232         return handle_up_down(+1);
233 }
234 int TransitionLengthText::handle_down_event()
235 {
236         return handle_up_down(-1);
237 }
238
239
240 TransitionPopup::TransitionPopup(MWindow *mwindow, MWindowGUI *gui)
241  : BC_PopupMenu(0, 0, 0, "", 0)
242 {
243         this->mwindow = mwindow;
244         this->gui = gui;
245 }
246
247 TransitionPopup::~TransitionPopup()
248 {
249         delete length_thread;
250 //      delete dialog_thread;
251 }
252
253
254 void TransitionPopup::create_objects()
255 {
256         length_thread = new TransitionLengthThread(mwindow);
257 //      add_item(attach = new TransitionPopupAttach(mwindow, this));
258         add_item(show = new TransitionPopupShow(mwindow, this));
259         add_item(on = new TransitionPopupOn(mwindow, this));
260         add_item(length_item = new TransitionPopupLength(mwindow, this));
261         add_item(detach = new TransitionPopupDetach(mwindow, this));
262 }
263
264 int TransitionPopup::update(Transition *transition)
265 {
266         this->transition = transition;
267         show->set_checked(transition->show);
268         on->set_checked(transition->on);
269         char len_text[50];
270         sprintf(len_text, _("Length: %2.2f sec"), transition->track->from_units(transition->length));
271         length_item->set_text(len_text);
272         return 0;
273 }
274
275
276 TransitionPopupAttach::TransitionPopupAttach(MWindow *mwindow, TransitionPopup *popup)
277  : BC_MenuItem(_("Attach..."))
278 {
279         this->mwindow = mwindow;
280         this->popup = popup;
281 }
282
283 TransitionPopupAttach::~TransitionPopupAttach()
284 {
285 }
286
287 int TransitionPopupAttach::handle_event()
288 {
289 //      popup->dialog_thread->start();
290         return 1;
291 }
292
293
294 TransitionPopupDetach::TransitionPopupDetach(MWindow *mwindow, TransitionPopup *popup)
295  : BC_MenuItem(_("Detach"))
296 {
297         this->mwindow = mwindow;
298         this->popup = popup;
299 }
300
301 TransitionPopupDetach::~TransitionPopupDetach()
302 {
303 }
304
305 int TransitionPopupDetach::handle_event()
306 {
307         mwindow->detach_transition(popup->transition);
308         return 1;
309 }
310
311
312 TransitionPopupOn::TransitionPopupOn(MWindow *mwindow, TransitionPopup *popup)
313  : BC_MenuItem(_("On"))
314 {
315         this->mwindow = mwindow;
316         this->popup = popup;
317 }
318
319 TransitionPopupOn::~TransitionPopupOn()
320 {
321 }
322
323 int TransitionPopupOn::handle_event()
324 {
325         popup->transition->on = !get_checked();
326         mwindow->sync_parameters(CHANGE_EDL);
327         return 1;
328 }
329
330
331 TransitionPopupShow::TransitionPopupShow(MWindow *mwindow, TransitionPopup *popup)
332  : BC_MenuItem(_("Show"))
333 {
334         this->mwindow = mwindow;
335         this->popup = popup;
336 }
337
338 TransitionPopupShow::~TransitionPopupShow()
339 {
340 }
341
342 int TransitionPopupShow::handle_event()
343 {
344         mwindow->show_plugin(popup->transition);
345         return 1;
346 }
347
348
349 TransitionPopupLength::TransitionPopupLength(MWindow *mwindow, TransitionPopup *popup)
350  : BC_MenuItem(_("Length"))
351 {
352         this->mwindow = mwindow;
353         this->popup = popup;
354 }
355
356 TransitionPopupLength::~TransitionPopupLength()
357 {
358 }
359
360 int TransitionPopupLength::handle_event()
361 {
362         Transition *transition = popup->transition;
363         double length = transition->edit->track->from_units(transition->length);
364         popup->length_thread->start(popup->transition, length);
365         return 1;
366 }
367