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