Credit Andrew added returns + vulkan patch
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / timelinepane.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  * 
19  */
20
21 #include "bcsignals.h"
22 #include "edl.h"
23 #include "timelinepane.h"
24 #include "localsession.h"
25 #include "maincursor.h"
26 #include "mtimebar.h"
27 #include "mwindow.h"
28 #include "mwindowgui.h"
29 #include "patchbay.h"
30 #include "samplescroll.h"
31 #include "theme.h"
32 #include "track.h"
33 #include "tracks.h"
34 #include "trackcanvas.h"
35 #include "trackscroll.h"
36
37
38 // coordinates are relative to the main window
39 TimelinePane::TimelinePane(MWindow *mwindow,
40         int number,
41         int x,
42         int y,
43         int w,
44         int h)
45 {
46 // printf("TimelinePane::TimelinePane %d number=%d %d %d %d %d\n",
47 // __LINE__,
48 // number,
49 // x,
50 // y,
51 // w,
52 // h);
53         this->mwindow = mwindow;
54         this->number = number;
55         this->x = x;
56         this->y = y;
57         this->w = w;
58         this->h = h;
59         patchbay = 0;
60         timebar = 0;
61         samplescroll = 0;
62         trackscroll = 0;
63         cursor = 0;
64 }
65
66 TimelinePane::~TimelinePane()
67 {
68         delete canvas;
69         delete cursor;
70         delete patchbay;
71         delete timebar;
72         delete samplescroll;
73         delete trackscroll;
74 }
75
76 void TimelinePane::create_objects()
77 {
78         this->gui = mwindow->gui;
79         mwindow->theme->get_pane_sizes(gui,
80                 &view_x,
81                 &view_y,
82                 &view_w,
83                 &view_h,
84                 number,
85                 x,
86                 y,
87                 w,
88                 h);
89         cursor = new MainCursor(mwindow, this);
90         cursor->create_objects();
91 // printf("TimelinePane::create_objects %d number=%d x=%d y=%d w=%d h=%d view_x=%d view_w=%d\n",
92 // __LINE__,
93 // number,
94 // x,
95 // y,
96 // w,
97 // h,
98 // view_x,
99 // view_w);
100
101
102         gui->add_subwindow(canvas = new TrackCanvas(mwindow,
103                 this,
104                 view_x,
105                 view_y,
106                 view_w,
107                 view_h));
108         canvas->create_objects();
109
110         if(number == TOP_LEFT_PANE ||
111                 number == BOTTOM_LEFT_PANE)
112         {
113                 int patchbay_y = y;
114                 int patchbay_h = h;
115
116                 if(number == TOP_LEFT_PANE)
117                 {
118                         patchbay_y += mwindow->theme->mtimebar_h;
119                         patchbay_h -= mwindow->theme->mtimebar_h;
120                 }
121
122                 gui->add_subwindow(patchbay = new PatchBay(mwindow,
123                         this,
124                         x,
125                         patchbay_y,
126                         mwindow->theme->patchbay_w,
127                         patchbay_h));
128                 patchbay->create_objects();
129         }
130
131         if(number == TOP_LEFT_PANE ||
132                 number == TOP_RIGHT_PANE)
133         {
134                 int timebar_w = view_w;
135 // Overlap right scrollbar
136                 if(gui->total_panes() == 1 ||
137                         number == TOP_RIGHT_PANE)
138                         timebar_w += BC_ScrollBar::get_span(SCROLL_VERT);
139
140                 gui->add_subwindow(timebar = new MTimeBar(mwindow,
141                         this,
142                         view_x,
143                         y,
144                         timebar_w,
145                         mwindow->theme->mtimebar_h));
146                 timebar->create_objects();
147         }
148
149         create_sample_scroll(view_x, view_y, view_w, view_h);
150
151         create_track_scroll(view_x, view_y, view_w, view_h);
152 }
153
154
155
156 void TimelinePane::resize_event(int x, int y, int w, int h)
157 {
158         this->x = x;
159         this->y = y;
160         this->w = w;
161         this->h = h;
162         mwindow->theme->get_pane_sizes(
163                 gui,
164                 &view_x,
165                 &view_y,
166                 &view_w,
167                 &view_h,
168                 number,
169                 x,
170                 y,
171                 w,
172                 h);
173 // printf("TimelinePane::resize_event %d number=%d x=%d y=%d w=%d h=%d view_x=%d view_y=%d view_w=%d view_h=%d\n",
174 // __LINE__,
175 // number,
176 // x,
177 // y,
178 // w,
179 // h,
180 // view_x,
181 // view_y,
182 // view_w,
183 // view_h);
184
185         if(timebar)
186         {
187                 int timebar_w = view_w;
188 // Overlap right scrollbar
189                 if(gui->total_panes() == 1 ||
190                         (gui->total_panes() == 2 &&
191                         (number == TOP_LEFT_PANE ||
192                         number == BOTTOM_LEFT_PANE)) ||
193                         number == TOP_RIGHT_PANE ||
194                         number == BOTTOM_RIGHT_PANE)
195                         timebar_w += BC_ScrollBar::get_span(SCROLL_VERT);
196                 timebar->resize_event(view_x,
197                         y,
198                         timebar_w,
199                         mwindow->theme->mtimebar_h);
200         }
201
202         if(patchbay)
203         {
204                 int patchbay_y = y;
205                 int patchbay_h = h;
206
207                 if(number == TOP_LEFT_PANE)
208                 {
209                         patchbay_y += mwindow->theme->mtimebar_h;
210                         patchbay_h -= mwindow->theme->mtimebar_h;
211                 }
212                 else
213                 {
214                 }
215
216                 patchbay->resize_event(x,
217                         patchbay_y,
218                         mwindow->theme->patchbay_w,
219                         patchbay_h);
220         }
221
222         if(samplescroll)
223         {
224                 if(gui->pane[TOP_LEFT_PANE] &&
225                         gui->pane[BOTTOM_LEFT_PANE] &&
226                         (number == TOP_LEFT_PANE ||
227                                 number == TOP_RIGHT_PANE))
228                 {
229                         delete samplescroll;
230                         samplescroll = 0;
231                 }
232                 else
233                 {
234                         samplescroll->resize_event(view_x,
235                                 view_y + view_h,
236                                 view_w);
237                         samplescroll->set_position();
238                 }
239         }
240         else
241                 create_sample_scroll(view_x, view_y, view_w, view_h);
242
243         if(trackscroll)
244         {
245                 if(gui->pane[TOP_LEFT_PANE] &&
246                         gui->pane[TOP_RIGHT_PANE] &&
247                         (number == TOP_LEFT_PANE ||
248                         number == BOTTOM_LEFT_PANE))
249                 {
250                         delete trackscroll;
251                         trackscroll = 0;
252                 }
253                 else
254                 {
255                         trackscroll->resize_event(view_x + view_w,
256                                 view_y,
257                                 view_h);
258                         trackscroll->set_position();
259                 }
260         }
261         else
262                 create_track_scroll(view_x, view_y, view_w, view_h);
263
264         canvas->reposition_window(view_x, view_y, view_w, view_h);
265         canvas->resize_event();
266 }
267
268 void TimelinePane::create_sample_scroll(int view_x, int view_y, int view_w, int view_h)
269 {
270 //printf("TimelinePane::create_sample_scroll %d %d\n", __LINE__, number);
271         if(number == BOTTOM_LEFT_PANE ||
272                 number == BOTTOM_RIGHT_PANE ||
273                 (gui->total_panes() == 2 &&
274                         gui->pane[TOP_LEFT_PANE] &&
275                         gui->pane[TOP_RIGHT_PANE]) ||
276                 gui->total_panes() == 1)
277         {
278 //printf("TimelinePane::create_sample_scroll %d %d %d\n", __LINE__, y, h);
279                 gui->add_subwindow(samplescroll = new SampleScroll(mwindow,
280                         this,
281                         view_x,
282                         y + h - BC_ScrollBar::get_span(SCROLL_VERT),
283                         view_w));
284                 samplescroll->set_position();
285         }
286 }
287
288 void TimelinePane::create_track_scroll(int view_x, int view_y, int view_w, int view_h)
289 {
290         if(number == TOP_RIGHT_PANE ||
291                 number == BOTTOM_RIGHT_PANE ||
292                 gui->vertical_panes() ||
293                 gui->total_panes() == 1)
294         {
295                 gui->add_subwindow(trackscroll = new TrackScroll(mwindow,
296                         this,
297                         view_x + view_w,
298                         view_y,
299                         view_h));
300                 trackscroll->set_position();
301         }
302 }
303
304
305 void TimelinePane::update(int scrollbars,
306         int do_canvas,
307         int timebar,
308         int patchbay)
309 {
310         if(timebar && this->timebar) this->timebar->update(0);
311         if(scrollbars) {
312                 if(samplescroll && this->samplescroll) samplescroll->set_position();
313                 if(trackscroll && this->trackscroll) trackscroll->set_position();
314         }
315         if(patchbay && this->patchbay) this->patchbay->update();
316
317         if( do_canvas != NO_DRAW ) {
318                 this->canvas->draw(do_canvas, 1);
319                 this->cursor->show();
320                 this->canvas->flash(0);
321 // Activate causes the menubar to deactivate.  Don't want this for
322 // picon thread.
323 //              if(do_canvas != IGNORE_THREAD) this->canvas->activate();
324         }
325 }
326
327 void TimelinePane::activate()
328 {
329         canvas->activate();
330         gui->focused_pane = number;
331 }
332
333 Track *TimelinePane::over_track()
334 {
335         int canvas_x = canvas->get_relative_cursor_x();
336         if( canvas_x < 0 || canvas_x >= canvas->get_w() ) return 0;
337         int canvas_y = canvas->get_relative_cursor_y();
338         if( canvas_y < 0 || canvas_y >= canvas->get_h() ) return 0;
339         int pane_y = canvas_y + mwindow->edl->local_session->track_start[number];
340         for( Track *track=mwindow->edl->tracks->first; track; track=track->next ) {
341                 int track_y = track->y_pixel;
342                 if( pane_y < track_y ) continue;
343                 track_y += track->vertical_span(mwindow->theme);
344                 if( pane_y < track_y )
345                         return track;
346         }
347
348         return 0;
349 }
350
351 Track *TimelinePane::over_patchbay()
352 {
353         if( !patchbay ) return 0;
354         int patch_x = patchbay->get_relative_cursor_x() ;
355         if( patch_x < 0 || patch_x >= patchbay->get_w() ) return 0;
356         int patch_y = patchbay->get_relative_cursor_y();
357         if( patch_y < 0 || patch_y >= patchbay->get_h() ) return 0;
358 //      int canvas_x = patch_x + patchbay->get_x() - canvas->get_x();
359         int canvas_y = patch_y + patchbay->get_y() - canvas->get_y();
360         int pane_y = canvas_y + mwindow->edl->local_session->track_start[number];
361         for( Track *track=mwindow->edl->tracks->first; track; track=track->next ) {
362                 int track_y = track->y_pixel;
363                 if( pane_y < track_y ) continue;
364                 track_y += track->vertical_span(mwindow->theme);
365                 if( pane_y < track_y )
366                         return track;
367         }
368
369         return 0;
370 }
371