r1014: Enable horizontal scrolling with the mouse wheel by pressing Ctrl.
[cinelerra_cv/ct.git] / cinelerra / apatchgui.C
blob3936287839f5181f2d114bcee3eccc5390bae8ae
1 #include "apatchgui.h"
2 #include "apatchgui.inc"
3 #include "atrack.h"
4 #include "autoconf.h"
5 #include "automation.h"
6 #include "edl.h"
7 #include "edlsession.h"
8 #include "floatauto.h"
9 #include "floatautos.h"
10 #include "language.h"
11 #include "localsession.h"
12 #include "mainundo.h"
13 #include "mwindow.h"
14 #include "mwindowgui.h"
15 #include "panauto.h"
16 #include "panautos.h"
17 #include "patchbay.h"
18 #include "theme.h"
19 #include "trackcanvas.h"
24 APatchGUI::APatchGUI(MWindow *mwindow, 
25         PatchBay *patchbay, 
26         ATrack *track, 
27         int x, 
28         int y)
29  : PatchGUI(mwindow, 
30         patchbay, 
31         track, 
32         x, 
33         y)
35         data_type = TRACK_AUDIO;
36         this->atrack = track;
37         meter = 0;
38         pan = 0;
39         fade = 0;
41 APatchGUI::~APatchGUI()
43         if(fade) delete fade;
44         if(meter) delete meter;
45         if(pan) delete pan;
48 int APatchGUI::create_objects()
50         return update(x, y);
53 int APatchGUI::reposition(int x, int y)
55         int x1 = 0;
56         int y1 = PatchGUI::reposition(x, y);
58         if(fade) fade->reposition_window(fade->get_x(), 
59                 y1 + y);
60         y1 += mwindow->theme->fade_h;
62         if(meter) meter->reposition_window(meter->get_x(),
63                 y1 + y,
64                 meter->get_w());
65         y1 += mwindow->theme->meter_h;
67         if(pan) pan->reposition_window(pan->get_x(),
68                 y1 + y);
70         if(nudge) nudge->reposition_window(nudge->get_x(),
71                 y1 + y);
73         y1 += mwindow->theme->pan_h;
74         return y1;
77 int APatchGUI::update(int x, int y)
79         int h = track->vertical_span(mwindow->theme);
80         int x1 = 0;
81         int y1 = PatchGUI::update(x, y);
83         if(fade)
84         {
85                 if(h - y1 < mwindow->theme->fade_h)
86                 {
87                         delete fade;
88                         fade = 0;
89                 }
90                 else
91                 {
92                         FloatAuto *previous = 0, *next = 0;
93                         double unit_position = mwindow->edl->local_session->get_selectionstart(1);
94                         unit_position = mwindow->edl->align_to_frame(unit_position, 0);
95                         unit_position = atrack->to_units(unit_position, 0);
96                         FloatAutos *ptr = (FloatAutos*)atrack->automation->autos[AUTOMATION_FADE];
97                         float value = ptr->get_value(
98                                 (long)unit_position,
99                                 PLAY_FORWARD, 
100                                 previous, 
101                                 next);
102                         fade->update(fade->get_w(),
103                                      value, 
104                                      mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_AUDIO_FADE],
105                                      mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_AUDIO_FADE]);
106                 }
107         }
108         else
109         if(h - y1 >= mwindow->theme->fade_h)
110         {
111                 patchbay->add_subwindow(fade = new AFadePatch(mwindow, 
112                         this, 
113                         x1 + x, 
114                         y1 + y, 
115                         patchbay->get_w() - 10));
116         }
117         y1 += mwindow->theme->fade_h;
119         if(meter)
120         {
121                 if(h - y1 < mwindow->theme->meter_h)
122                 {
123                         delete meter;
124                         meter = 0;
125                 }
126         }
127         else
128         if(h - y1 >= mwindow->theme->meter_h)
129         {
130                 patchbay->add_subwindow(meter = new AMeterPatch(mwindow,
131                         this,
132                         x1 + x, 
133                         y1 + y));
134         }
135         y1 += mwindow->theme->meter_h;
136         x1 += 10;
138         if(pan)
139         {
140                 if(h - y1 < mwindow->theme->pan_h)
141                 {
142                         delete pan;
143                         pan = 0;
144                         delete nudge;
145                         nudge = 0;
146                 }
147                 else
148                 {
149                         if(pan->get_total_values() != mwindow->edl->session->audio_channels)
150                         {
151                                 pan->change_channels(mwindow->edl->session->audio_channels,
152                                         mwindow->edl->session->achannel_positions);
153                         }
154                         else
155                         {
156                                 int handle_x, handle_y;
157                                 PanAuto *previous = 0, *next = 0;
158                                 double unit_position = mwindow->edl->local_session->get_selectionstart(1);
159                                 unit_position = mwindow->edl->align_to_frame(unit_position, 0);
160                                 unit_position = atrack->to_units(unit_position, 0);
161                                 PanAutos *ptr = (PanAutos*)atrack->automation->autos[AUTOMATION_PAN];
162                                 ptr->get_handle(handle_x,
163                                         handle_y,
164                                         (long)unit_position, 
165                                         PLAY_FORWARD,
166                                         previous,
167                                         next);
168                                 pan->update(handle_x, handle_y);
169                         }
170                         nudge->update();
171                 }
172         }
173         else
174         if(h - y1 >= mwindow->theme->pan_h)
175         {
176                 patchbay->add_subwindow(pan = new APanPatch(mwindow,
177                         this,
178                         x1 + x, 
179                         y1 + y));
180                 x1 += pan->get_w() + 10;
181                 patchbay->add_subwindow(nudge = new NudgePatch(mwindow,
182                         this,
183                         x1 + x,
184                         y1 + y,
185                         patchbay->get_w() - x1 - 10));
186         }
187         y1 += mwindow->theme->pan_h;
189         return y1;
192 void APatchGUI::synchronize_fade(float value_change)
194         if(fade && !change_source) 
195         {
196                 fade->update(fade->get_value() + value_change);
197                 fade->update_edl();
198         }
203 AFadePatch::AFadePatch(MWindow *mwindow, APatchGUI *patch, int x, int y, int w)
204  : BC_FSlider(x, 
205                         y, 
206                         0, 
207                         w, 
208                         w, 
209                         mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_AUDIO_FADE], 
210                         mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_AUDIO_FADE], 
211                         get_keyframe(mwindow, patch)->value)
213         this->mwindow = mwindow;
214         this->patch = patch;
217 float AFadePatch::update_edl()
219         FloatAuto *current;
220         double position = mwindow->edl->local_session->get_selectionstart(1);
221         Autos *fade_autos = patch->atrack->automation->autos[AUTOMATION_FADE];
222         int need_undo = !fade_autos->auto_exists_for_editing(position);
224         current = (FloatAuto*)fade_autos->get_auto_for_editing(position);
226         float result = get_value() - current->value;
227         current->value = get_value();
229         mwindow->undo->update_undo(_("fade"), 
230                 LOAD_AUTOMATION, 
231                 need_undo ? 0 : this);
233         return result;
237 int AFadePatch::handle_event()
239         if(shift_down()) 
240         {
241                 update(0.0);
242                 set_tooltip(get_caption());
243         }
245         patch->change_source = 1;
246         float change = update_edl();
247         if(patch->track->gang) 
248                 patch->patchbay->synchronize_faders(change, TRACK_AUDIO, patch->track);
249         patch->change_source = 0;
251         mwindow->sync_parameters(CHANGE_PARAMS);
253         if(mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE])
254         {
255                 mwindow->gui->canvas->draw_overlays();
256                 mwindow->gui->canvas->flash();
257         }
258         return 1;
261 FloatAuto* AFadePatch::get_keyframe(MWindow *mwindow, APatchGUI *patch)
263         Auto *current = 0;
264         double unit_position = mwindow->edl->local_session->get_selectionstart(1);
265         unit_position = mwindow->edl->align_to_frame(unit_position, 0);
266         unit_position = patch->atrack->to_units(unit_position, 0);
268         FloatAutos *ptr = (FloatAutos*)patch->atrack->automation->autos[AUTOMATION_FADE];
269         return (FloatAuto*)ptr->get_prev_auto(
270                 (long)unit_position, 
271                 PLAY_FORWARD,
272                 current);
276 APanPatch::APanPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
277  : BC_Pan(x, 
278                 y, 
279                 PAN_RADIUS, 
280                 MAX_PAN, 
281                 mwindow->edl->session->audio_channels, 
282                 mwindow->edl->session->achannel_positions, 
283                 get_keyframe(mwindow, patch)->handle_x, 
284                 get_keyframe(mwindow, patch)->handle_y,
285                 get_keyframe(mwindow, patch)->values)
287         this->mwindow = mwindow;
288         this->patch = patch;
289         set_tooltip("Pan");
292 int APanPatch::handle_event()
294         PanAuto *current;
295         double position = mwindow->edl->local_session->get_selectionstart(1);
296         Autos *pan_autos = patch->atrack->automation->autos[AUTOMATION_PAN];
297         int need_undo = !pan_autos->auto_exists_for_editing(position);
299         current = (PanAuto*)pan_autos->get_auto_for_editing(position);
301         current->handle_x = get_stick_x();
302         current->handle_y = get_stick_y();
303         memcpy(current->values, get_values(), sizeof(float) * mwindow->edl->session->audio_channels);
305         mwindow->undo->update_undo(_("pan"), LOAD_AUTOMATION, need_undo ? 0 : this);
307         mwindow->sync_parameters(CHANGE_PARAMS);
309         if(need_undo && mwindow->edl->session->auto_conf->autos[AUTOMATION_PAN])
310         {
311                 mwindow->gui->canvas->draw_overlays();
312                 mwindow->gui->canvas->flash();
313         }
314         return 1;
317 PanAuto* APanPatch::get_keyframe(MWindow *mwindow, APatchGUI *patch)
319         Auto *current = 0;
320         double unit_position = mwindow->edl->local_session->get_selectionstart(1);
321         unit_position = mwindow->edl->align_to_frame(unit_position, 0);
322         unit_position = patch->atrack->to_units(unit_position, 0);
324         PanAutos *ptr = (PanAutos*)patch->atrack->automation->autos[AUTOMATION_PAN];
325         return (PanAuto*)ptr->get_prev_auto(
326                 (long)unit_position, 
327                 PLAY_FORWARD,
328                 current);
334 AMeterPatch::AMeterPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
335  : BC_Meter(x, 
336                         y, 
337                         METER_HORIZ, 
338                         patch->patchbay->get_w() - 10, 
339                         mwindow->edl->session->min_meter_db, 
340                         mwindow->edl->session->max_meter_db, 
341                         mwindow->edl->session->meter_format, 
342                         0,
343                         TRACKING_RATE * 10,
344                         TRACKING_RATE)
346         this->mwindow = mwindow;
347         this->patch = patch;
350 int AMeterPatch::button_press_event()
352         if(cursor_inside() && is_event_win() && get_buttonpress() == 1)
353         {
354                 mwindow->reset_meters();
355                 return 1;
356         }
358         return 0;