f41959acfd7824f20834129e5dafd54eea71aa4a
[goodguy/history.git] / cinelerra-5.1 / cinelerra / apatchgui.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 "apatchgui.h"
23 #include "atrack.h"
24 #include "autoconf.h"
25 #include "automation.h"
26 #include "edl.h"
27 #include "edlsession.h"
28 #include "floatauto.h"
29 #include "floatautos.h"
30 #include "gwindowgui.h"
31 #include "intauto.h"
32 #include "intautos.h"
33 #include "language.h"
34 #include "localsession.h"
35 #include "mainsession.h"
36 #include "mainundo.h"
37 #include "mwindow.h"
38 #include "mwindowgui.h"
39 #include "panauto.h"
40 #include "panautos.h"
41 #include "patchbay.h"
42 #include "theme.h"
43 #include "trackcanvas.h"
44 #include "zwindow.h"
45
46 APatchGUI::APatchGUI(MWindow *mwindow, PatchBay *patchbay,
47                 ATrack *track, int x, int y)
48  : PatchGUI(mwindow, patchbay, track, x, y)
49 {
50         data_type = TRACK_AUDIO;
51         this->atrack = track;
52         meter = 0;
53         pan = 0;
54         fade = 0;
55 }
56
57 APatchGUI::~APatchGUI()
58 {
59         if( fade ) delete fade;
60         if( meter ) delete meter;
61         if( pan ) delete pan;
62 }
63
64 void APatchGUI::create_objects()
65 {
66         update(x, y);
67 }
68
69 int APatchGUI::reposition(int x, int y)
70 {
71         int y1 = PatchGUI::reposition(x, y);
72
73         if( fade )
74                 fade->reposition_window(fade->get_x(), y1+y);
75         y1 += mwindow->theme->fade_h;
76         if( meter )
77                 meter->reposition_window(meter->get_x(), y1+y, -1, meter->get_w());
78         y1 += mwindow->theme->meter_h;
79         if( mix )
80                 mix->reposition_window(mix->get_x(), y1+y);
81         if( pan )
82                 pan->reposition_window(pan->get_x(), y1+y);
83         if( nudge )
84                 nudge->reposition_window(nudge->get_x(), y1+y);
85         y1 += mwindow->theme->pan_h;
86
87         return y1;
88 }
89
90 int APatchGUI::update(int x, int y)
91 {
92         int h = track->vertical_span(mwindow->theme);
93         int x1 = 0;
94         int y1 = PatchGUI::update(x, y);
95
96         int y2 = y1 + mwindow->theme->fade_h;
97         if( fade ) {
98                 if( h < y2 ) {
99                         delete fade;
100                         fade = 0;
101                 }
102                 else {
103                         FloatAuto *previous = 0, *next = 0;
104                         double unit_position = mwindow->edl->local_session->get_selectionstart(1);
105                         unit_position = mwindow->edl->align_to_frame(unit_position, 0);
106                         unit_position = atrack->to_units(unit_position, 0);
107                         FloatAutos *ptr = (FloatAutos*)atrack->automation->autos[AUTOMATION_FADE];
108                         float value = ptr->get_value((long)unit_position, PLAY_FORWARD, previous, next);
109                         fade->update(fade->get_w(), value,
110                                      mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_AUDIO_FADE],
111                                      mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_AUDIO_FADE]);
112                 }
113         }
114         else if( h >= y2 ) {
115                 patchbay->add_subwindow(fade = new AFadePatch(mwindow, this, x1+x, y1+y,
116                         patchbay->get_w() - 10));
117         }
118         if( fade )
119                 y1 = y2;
120
121         y2 = y1 + mwindow->theme->meter_h;
122         if( meter ) {
123                 if( h < y2 ) {
124                         delete meter;  meter = 0;
125                 }
126         }
127         else if( h >= y2 ) {
128                 patchbay->add_subwindow(meter = new AMeterPatch(mwindow, this, x1+x, y1+y));
129         }
130         if( meter )
131                 y1 = y2;
132
133         y2 = y1 + mwindow->theme->pan_h;
134         if( pan ) {
135                 if( h < y2 ) {
136                         delete mix;    mix = 0;
137                         delete pan;    pan = 0;
138                         delete nudge;  nudge = 0;
139                 }
140                 else {
141                         if( mwindow->session->selected_zwindow >= 0 ) {
142                                 int v = mwindow->mixer_track_active(track);
143                                 mix->update(v);
144                         }
145                         if( pan->get_total_values() != mwindow->edl->session->audio_channels ) {
146                                 pan->change_channels(mwindow->edl->session->audio_channels,
147                                         mwindow->edl->session->achannel_positions);
148                         }
149                         else {
150                                 int handle_x, handle_y;
151                                 PanAuto *previous = 0, *next = 0;
152                                 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
153                                 unit_position = mwindow->edl->align_to_frame(unit_position, 0);
154                                 unit_position = atrack->to_units(unit_position, 0);
155                                 PanAutos *ptr = (PanAutos*)atrack->automation->autos[AUTOMATION_PAN];
156                                 ptr->get_handle(handle_x, handle_y, (long)unit_position,
157                                                 PLAY_FORWARD, previous, next);
158                                 pan->update(handle_x, handle_y);
159                         }
160                         nudge->update();
161                 }
162         }
163         else if( h >= y2 ) {
164                 patchbay->add_subwindow(mix = new AMixPatch(mwindow, this, x1+x, y1+y+5));
165                 x1 += mix->get_w() + 10;
166                 patchbay->add_subwindow(pan = new APanPatch(mwindow, this, x1+x, y1+y));
167                 x1 += pan->get_w() + 20;
168                 patchbay->add_subwindow(nudge = new NudgePatch(mwindow, this, x1+x, y1+y,
169                                 patchbay->get_w() - x1-x - 10));
170         }
171         if( pan )
172                 y1 = y2;
173
174         return y1;
175 }
176
177 void APatchGUI::synchronize_fade(float value_change)
178 {
179         if( fade && !change_source ) {
180                 fade->update(fade->get_value() + value_change);
181                 fade->update_edl();
182         }
183 }
184
185
186
187 AFadePatch::AFadePatch(MWindow *mwindow, APatchGUI *patch, int x, int y, int w)
188  : BC_FSlider(x, y, 0, w, w,
189         mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_AUDIO_FADE],
190         mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_AUDIO_FADE],
191         mwindow->get_float_auto(patch, AUTOMATION_FADE)->get_value())
192 {
193         this->mwindow = mwindow;
194         this->patch = patch;
195 }
196
197 float AFadePatch::update_edl()
198 {
199         FloatAuto *current;
200         double position = mwindow->edl->local_session->get_selectionstart(1);
201         Autos *fade_autos = patch->atrack->automation->autos[AUTOMATION_FADE];
202         int need_undo = !fade_autos->auto_exists_for_editing(position);
203
204         mwindow->undo->update_undo_before(_("fade"), need_undo ? 0 : this);
205
206         current = (FloatAuto*)fade_autos->get_auto_for_editing(position);
207
208         float result = get_value() - current->get_value();
209         current->set_value(this->get_value());
210
211         mwindow->undo->update_undo_after(_("fade"), LOAD_AUTOMATION);
212
213         return result;
214 }
215
216
217 int AFadePatch::handle_event()
218 {
219         if( shift_down() ) {
220                 update(0.0);
221                 set_tooltip(get_caption());
222         }
223
224         patch->change_source = 1;
225         float change = update_edl();
226         if( patch->track->gang && patch->track->record )
227                 patch->patchbay->synchronize_faders(change, TRACK_AUDIO, patch->track);
228         patch->change_source = 0;
229
230         mwindow->sync_parameters(CHANGE_PARAMS);
231
232         if( mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE] ) {
233                 mwindow->gui->draw_overlays(1);
234         }
235         return 1;
236 }
237
238 AKeyFadePatch::AKeyFadePatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
239  : BC_SubWindow(x,y, patch->patchbay->get_w(),20,
240         GWindowGUI::auto_colors[AUTOMATION_FADE])
241 {
242         this->mwindow = mwindow;
243         this->patch = patch;
244 }
245
246 void AKeyFadePatch::create_objects()
247 {
248         akey_fade_value = new AKeyFadeValue(this);
249         add_subwindow(akey_fade_value);
250         akey_fade_value->activate();
251         show_window();
252 }
253
254 AKeyFadeValue::AKeyFadeValue(AKeyFadePatch *akey_fade_patch)
255  : AFadePatch(akey_fade_patch->mwindow, akey_fade_patch->patch,
256         0,0, akey_fade_patch->get_w())
257 {
258         this->akey_fade_patch = akey_fade_patch;
259 }
260
261 int AKeyFadeValue::button_release_event()
262 {
263         AFadePatch::button_release_event();
264         return 0;
265 }
266
267 int AKeyFadeValue::handle_event()
268 {
269         APatchGUI *patch = akey_fade_patch->patch;
270         int ret = AFadePatch::handle_event();
271         AFadePatch *fade = patch->fade;
272         if( fade )
273                 fade->update(get_value());
274         return ret;
275 }
276
277
278 APanPatch::APanPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
279  : BC_Pan(x, y, PAN_RADIUS, MAX_PAN,
280         mwindow->edl->session->audio_channels,
281         mwindow->edl->session->achannel_positions,
282         mwindow->get_pan_auto(patch)->handle_x,
283         mwindow->get_pan_auto(patch)->handle_y,
284         mwindow->get_pan_auto(patch)->values)
285 {
286         this->mwindow = mwindow;
287         this->patch = patch;
288         set_tooltip(_("Pan"));
289 }
290
291 int APanPatch::handle_event()
292 {
293         PanAuto *current;
294         double position = mwindow->edl->local_session->get_selectionstart(1);
295         Autos *pan_autos = patch->atrack->automation->autos[AUTOMATION_PAN];
296         int need_undo = !pan_autos->auto_exists_for_editing(position);
297
298         mwindow->undo->update_undo_before(_("pan"), need_undo ? 0 : this);
299
300         current = (PanAuto*)pan_autos->get_auto_for_editing(position);
301
302         current->handle_x = get_stick_x();
303         current->handle_y = get_stick_y();
304         memcpy(current->values, get_values(), sizeof(float) * mwindow->edl->session->audio_channels);
305
306         mwindow->undo->update_undo_after(_("pan"), LOAD_AUTOMATION);
307
308         mwindow->sync_parameters(CHANGE_PARAMS);
309
310         if( need_undo && mwindow->edl->session->auto_conf->autos[AUTOMATION_PAN] ) {
311                 mwindow->gui->draw_overlays(1);
312         }
313         return 1;
314 }
315
316 AKeyPanPatch::AKeyPanPatch(MWindow *mwindow, APatchGUI *patch)
317  : APanPatch(mwindow, patch, -1,-1)
318 {
319 }
320
321 int AKeyPanPatch::button_release_event()
322 {
323         APanPatch::button_release_event();
324         return 0;
325 }
326
327 int AKeyPanPatch::handle_event()
328 {
329         int ret = APanPatch::handle_event();
330         APanPatch *pan = patch->pan;
331         if( pan )
332                 pan->update(get_stick_x(), get_stick_y());
333         return ret;
334 }
335
336
337 AMeterPatch::AMeterPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
338  : BC_Meter(x, y, METER_HORIZ, patch->patchbay->get_w() - 10,
339         mwindow->edl->session->min_meter_db, mwindow->edl->session->max_meter_db,
340         mwindow->edl->session->meter_format, 0, -1)
341 {
342         this->mwindow = mwindow;
343         this->patch = patch;
344         set_delays(TRACKING_RATE * 10,
345                         TRACKING_RATE);
346 }
347
348 int AMeterPatch::button_press_event()
349 {
350         if( cursor_inside() && is_event_win() && get_buttonpress() == 1 ) {
351                 mwindow->reset_meters();
352                 return 1;
353         }
354
355         return 0;
356 }
357
358 AMixPatch::AMixPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
359  : MixPatch(mwindow, patch, x, y)
360 {
361         set_tooltip(_("Mixer"));
362 }
363
364 AMixPatch::~AMixPatch()
365 {
366 }
367