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