fix audiospect ratio in scale per andrew, upgrade dav1d to 0.6.0, fix shapewipe black...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / zwindow.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2012 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 "bcdialog.h"
23 #include "edl.h"
24 #include "filexml.h"
25 #include "language.h"
26 #include "mainsession.h"
27 #include "mwindow.h"
28 #include "mwindowgui.h"
29 #include "patchbay.h"
30 #include "patchgui.h"
31 #include "playbackengine.h"
32 #include "renderengine.h"
33 #include "timelinepane.h"
34 #include "track.h"
35 #include "tracks.h"
36 #include "transportque.h"
37 #include "zwindow.h"
38 #include "zwindowgui.h"
39
40 Mixers::Mixers()
41 {
42 }
43
44 Mixers::~Mixers()
45 {
46         remove_all_objects();
47 }
48
49 Mixer *Mixers::new_mixer()
50 {
51         int idx = 0;
52         for( int i=0; i<size(); ++i ) {
53                 Mixer *mixer = get(i);
54                 if( idx < mixer->idx ) idx = mixer->idx;
55         }
56         return append(new Mixer(idx+1));
57 }
58
59 Mixer *Mixers::get_mixer(int idx)
60 {
61         for( int i=0; i<size(); ++i ) {
62                 Mixer *mixer = get(i);
63                 if( mixer->idx == idx ) return mixer;
64         }
65         return 0;
66 }
67
68 void Mixers::del_mixer(int idx)
69 {
70         Mixer *mixer = get_mixer(idx);
71         if( mixer ) remove_object(mixer);
72 }
73
74 void Mixer::set_title(const char *tp)
75 {
76         if( tp == title ) return;
77         strncpy(title, !tp ? "" : tp, sizeof(title));
78         title[sizeof(title)-1] = 0;
79 }
80
81 void Mixers::save(FileXML *file)
82 {
83         file->tag.set_title("MIXERS");
84         file->append_tag();
85         file->append_newline();
86         for( int i=0; i<size(); ++i ) {
87                 Mixer *mixer = get(i);
88                 mixer->save(file);
89         }
90         file->tag.set_title("/MIXERS");
91         file->append_tag();
92         file->append_newline();
93 }
94
95 int Mixers::load(FileXML *file)
96 {
97         int result = 0;
98         while( !(result = file->read_tag()) ) {
99                 if( file->tag.title_is("/MIXERS") ) break;
100                 if( file->tag.title_is("MIXER") ) {
101                         Mixer *mixer = new_mixer();
102                         file->tag.get_property("TITLE", mixer->title);
103                         mixer->x = file->tag.get_property("X", mixer->x);
104                         mixer->y = file->tag.get_property("Y", mixer->y);
105                         mixer->w = file->tag.get_property("W", mixer->w);
106                         mixer->h = file->tag.get_property("H", mixer->h);
107                         mixer->load(file);
108                 }
109         }
110         return 0;
111 }
112
113 void Mixers::copy_from(Mixers &that)
114 {
115         remove_all_objects();
116         for( int i=0; i<that.size(); ++i ) {
117                 Mixer *mixer = new_mixer();
118                 mixer->copy_from(*that[i]);
119         }
120 }
121
122 void Mixer::save(FileXML *file)
123 {
124         file->tag.set_title("MIXER");
125         file->tag.set_property("TITLE",title);
126         file->tag.set_property("X",x);
127         file->tag.set_property("Y",y);
128         file->tag.set_property("W",w);
129         file->tag.set_property("H",h);
130         file->append_tag();
131         file->append_newline();
132         for( int i=0; i<mixer_ids.size(); ++i ) {
133                 file->tag.set_title("MIX");
134                 file->tag.set_property("ID", mixer_ids[i]);
135                 file->append_tag();
136                 file->tag.set_title("/MIX");
137                 file->append_tag();
138                 file->append_newline();
139         }
140         file->tag.set_title("/MIXER");
141         file->append_tag();
142         file->append_newline();
143 }
144
145 Mixer::Mixer(int idx)
146 {
147         this->idx = idx;
148         title[0] = 0;
149         x = y = 100 + idx*64;
150         w = 400;  h = 300;
151 }
152 void Mixer::reposition(int x, int y, int w, int h)
153 {
154         this->x = x;  this->y = y;
155         this->w = w;  this->h = h;
156 }
157
158 int Mixer::load(FileXML *file)
159 {
160         int result = 0;
161         while( !(result = file->read_tag()) ) {
162                 if( file->tag.title_is("/MIXER") ) break;
163                 if( file->tag.title_is("MIX") ) {
164                         mixer_ids.append(file->tag.get_property("ID", 0));
165                 }
166         }
167         return 0;
168 }
169
170 void Mixer::copy_from(Mixer &that)
171 {
172         mixer_ids.remove_all();
173         strncpy(title, that.title, sizeof(title));
174         title[sizeof(title)-1] = 0;
175         x = that.x;  y = that.y;
176         w = that.w;  h = that.h;
177         for( int i=0; i<that.mixer_ids.size(); ++i )
178                 mixer_ids.append(that.mixer_ids[i]);
179 }
180
181
182 ZWindow::ZWindow(MWindow *mwindow)
183  : BC_DialogThread()
184 {
185         this->mwindow = mwindow;
186         idx = -1;
187         edl = 0;
188         highlighted = 0;
189         title[0] = 0;
190         zgui = 0;
191         zoom = 0;
192 }
193
194 ZWindow::~ZWindow()
195 {
196         close_window();
197         if( edl )
198                 edl->remove_user();
199 }
200
201 BC_Window* ZWindow::new_gui()
202 {
203         Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
204         zgui = new ZWindowGUI(mwindow, this, mixer);
205         zgui->create_objects();
206         return zgui;
207 }
208
209 void ZWindow::handle_done_event(int result)
210 {
211         stop_playback(1);
212         if( result )
213                 mwindow->del_mixer(this);
214         idx = -1;
215 }
216 void ZWindow::handle_close_event(int result)
217 {
218         zgui = 0;
219 }
220
221 void ZWindow::change_source(EDL *edl)
222 {
223         if( this->edl == edl ) return;
224         zgui->playback_engine->refresh_frame(CHANGE_ALL, edl);
225         if( this->edl )
226                 this->edl->remove_user();
227         this->edl = edl;
228 }
229
230 void ZWindow::stop_playback(int wait)
231 {
232         zgui->playback_engine->stop_playback(wait);
233 }
234
235 void ZWindow::handle_mixer(int command, int wait_tracking,
236                 int use_inout, int toggle_audio, int loop_play, float speed)
237 {
238         PlaybackEngine *engine = zgui->playback_engine;
239         engine->next_command->toggle_audio = toggle_audio;
240         engine->next_command->loop_play = loop_play;
241         engine->next_command->speed = speed;
242         engine->send_command(command, edl, wait_tracking, use_inout);
243 }
244
245 void ZWindow::update_mixer_ids()
246 {
247         if( !running() ) return;
248         Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
249         if( !mixer ) return;
250         mixer->mixer_ids.remove_all();
251         PatchBay *patchbay = mwindow->gui->pane[0]->patchbay;
252         for( int i=0; i<patchbay->patches.size(); ++i ) {
253                 PatchGUI *patchgui = patchbay->patches[i];
254                 if( !patchgui->mixer ) continue;
255                 int mixer_id = patchgui->track->get_mixer_id();
256                 if( mixer->mixer_ids.number_of(mixer_id) >= 0 ) continue;
257                 mixer->mixer_ids.append(mixer_id);
258         }
259 }
260
261 void ZWindow::set_title(const char *tp)
262 {
263         Track *track = 0;
264         Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
265         if( mixer ) {
266                 mixer->set_title(tp);
267                 for( track=mwindow->edl->tracks->first; track; track=track->next ) {
268                         if( track->data_type != TRACK_VIDEO ) continue;
269                         int mixer_id = track->get_mixer_id();
270                         int k = mixer->mixer_ids.size();
271                         while( --k >= 0 && mixer_id != mixer->mixer_ids[k] );
272                         if( k >= 0 ) break;
273                 }
274         }
275         char *cp = title, *ep = cp + sizeof(title)-1;
276         cp += snprintf(title, ep-cp, track ? track->title : _("Mixer %d"), idx);
277         if( tp ) cp += snprintf(cp, ep-cp, ": %s", tp);
278         *cp = 0;
279 }
280
281 void ZWindow::reposition(int x, int y, int w, int h)
282 {
283         Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
284         if( !mixer ) return;
285         mixer->reposition(x, y, w, h);
286 }
287