Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / cinelerra / mtimebar.C
blobe704e77e8f6797befeb459297f007fa3bbcac42e
1 #include "bcsignals.h"
2 #include "clip.h"
3 #include "cwindow.h"
4 #include "edl.h"
5 #include "edlsession.h"
6 #include "localsession.h"
7 #include "maincursor.h"
8 #include "mainsession.h"
9 #include "mbuttons.h"
10 #include "mtimebar.h"
11 #include "mwindowgui.h"
12 #include "mwindow.h"
13 #include "patchbay.h"
14 #include "preferences.h"
15 #include "theme.h"
16 #include "trackcanvas.h"
17 #include "tracks.h"
18 #include "transportque.h"
19 #include "zoombar.h"
23 MTimeBar::MTimeBar(MWindow *mwindow, 
24         MWindowGUI *gui,
25         int x, 
26         int y,
27         int w,
28         int h)
29  : TimeBar(mwindow, gui, x, y, w, h)
31         this->gui = gui;
35 int64_t MTimeBar::position_to_pixel(double position)
37         return (int64_t)(position * 
38                 mwindow->edl->session->sample_rate / 
39                 mwindow->edl->local_session->zoom_sample - 
40                 mwindow->edl->local_session->view_start);
44 void MTimeBar::stop_playback()
46         gui->unlock_window();
47         gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
48         gui->lock_window();
51 #define TEXT_MARGIN 4
52 #define TICK_SPACING 5
53 #define LINE_MARGIN 3
54 #define TICK_MARGIN 16
55 void MTimeBar::draw_time()
58         char string[BCTEXTLEN];
59         int sample_rate = mwindow->edl->session->sample_rate;
60         double frame_rate = mwindow->edl->session->frame_rate;
61         int64_t windowspan = 0;
62 // Seconds between text markings
63         double text_interval = 3600.0;
64 // Seconds between tick marks
65         double tick_interval = 3600.0;
66         int64_t timescale2 = 0;
67         float timescale3 = 0;
68         int pixel = 0;
71 // Calculate tick mark spacing, number spacing, and starting point based
72 // on zoom, time format, project settings.
74 // If the time format is for audio, mark round numbers of samples based on
75 // samplerate.
76 // Fow low zoom, mark tens of samples.
78 // If the time format is for video, mark round number of frames based on
79 // framerate.
80 // For low zoom, mark individual frames.
82         windowspan = mwindow->edl->local_session->zoom_sample * get_w();
85         draw_range();
91 // Number of seconds per pixel
92         double time_per_pixel = (double)mwindow->edl->local_session->zoom_sample / 
93                 sample_rate;
94 // Seconds in each frame
95         double frame_seconds = (double)1.0 / frame_rate;
96 // Starting time of view in seconds.
97         double view_start = mwindow->edl->local_session->view_start * time_per_pixel;
98 // Ending time of view in seconds
99         double view_end = (double)(mwindow->edl->local_session->view_start +
100                 get_w()) * time_per_pixel;
101 // Get minimum distance between text marks
102         int min_pixels1 = get_text_width(MEDIUMFONT, 
103                 Units::totext(string,
104                         view_start,
105                         mwindow->edl->session->time_format, 
106                         sample_rate,
107                         mwindow->edl->session->frame_rate,
108                         mwindow->edl->session->frames_per_foot)) + TEXT_MARGIN;
109         int min_pixels2 = get_text_width(MEDIUMFONT, 
110                 Units::totext(string,
111                         view_end,
112                         mwindow->edl->session->time_format, 
113                         sample_rate,
114                         mwindow->edl->session->frame_rate,
115                         mwindow->edl->session->frames_per_foot)) + TEXT_MARGIN;
116         int min_pixels = (int)MAX(min_pixels1, min_pixels2);
119 // Minimum seconds between text marks
120         double min_time = (double)min_pixels * 
121                 mwindow->edl->local_session->zoom_sample /
122                 sample_rate;
125 // Get first text mark on or before window start
126         int64_t starting_mark = 0;
128         int progression = 1;
130 // Default text spacing
131         text_interval = 0.5;
132         double prev_text_interval = 1.0;
134         while(text_interval >= min_time)
135         {
136                 prev_text_interval = text_interval;
137                 if(progression == 0)
138                 {
139                         text_interval /= 2;
140                         progression++;
141                 }
142                 else
143                 if(progression == 1)
144                 {
145                         text_interval /= 2;
146                         progression++;
147                 }
148                 else
149                 if(progression == 2)
150                 {
151                         text_interval /= 2.5;
152                         progression = 0;
153                 }
154         }
156         text_interval = prev_text_interval;
158         if(1 >= min_time)
159                 ;
160         else
161         if(2 >= min_time)
162                 text_interval = 2;
163         else
164         if(5 >= min_time)
165                 text_interval = 5;
166         else
167         if(10 >= min_time)
168                 text_interval = 10;
169         else
170         if(15 >= min_time)
171                 text_interval = 15;
172         else
173         if(20 >= min_time)
174                 text_interval = 20;
175         else
176         if(30 >= min_time)
177                 text_interval = 30;
178         else
179         if(60 >= min_time)
180                 text_interval = 60;
181         else
182         if(120 >= min_time)
183                 text_interval = 120;
184         else
185         if(300 >= min_time)
186                 text_interval = 300;
187         else
188         if(600 >= min_time)
189                 text_interval = 600;
190         else
191         if(1200 >= min_time)
192                 text_interval = 1200;
193         else
194         if(1800 >= min_time)
195                 text_interval = 1800;
196         else
197         if(3600 >= min_time)
198                 text_interval = 3600;
200 // Set text interval
201         switch(mwindow->edl->session->time_format)
202         {
203                 case TIME_FEET_FRAMES:
204                 {
205                         double foot_seconds = frame_seconds * mwindow->edl->session->frames_per_foot;
206                         if(frame_seconds >= min_time)
207                                 text_interval = frame_seconds;
208                         else
209                         if(foot_seconds / 8.0 > min_time)
210                                 text_interval = frame_seconds * mwindow->edl->session->frames_per_foot / 8.0;
211                         else
212                         if(foot_seconds / 4.0 > min_time)
213                                 text_interval = frame_seconds * mwindow->edl->session->frames_per_foot / 4.0;
214                         else
215                         if(foot_seconds / 2.0 > min_time)
216                                 text_interval = frame_seconds * mwindow->edl->session->frames_per_foot / 2.0;
217                         else
218                         if(foot_seconds > min_time)
219                                 text_interval = frame_seconds * mwindow->edl->session->frames_per_foot;
220                         else
221                         if(foot_seconds * 2 >= min_time)
222                                 text_interval = foot_seconds * 2;
223                         else
224                         if(foot_seconds * 5 >= min_time)
225                                 text_interval = foot_seconds * 5;
226                         else
227                         {
229                                 for(int factor = 10, progression = 0; factor <= 100000; )
230                                 {
231                                         if(foot_seconds * factor >= min_time)
232                                         {
233                                                 text_interval = foot_seconds * factor;
234                                                 break;
235                                         }
237                                         if(progression == 0)
238                                         {
239                                                 factor = (int)(factor * 2.5);
240                                                 progression++;
241                                         }
242                                         else
243                                         if(progression == 1)
244                                         {
245                                                 factor = (int)(factor * 2);
246                                                 progression++;
247                                         }
248                                         else
249                                         if(progression == 2)
250                                         {
251                                                 factor = (int)(factor * 2);
252                                                 progression = 0;
253                                         }
254                                 }
256                         }
257                         break;
258                 }
260                 case TIME_FRAMES:
261                 case TIME_HMSF:
262 // One frame per text mark
263                         if(frame_seconds >= min_time)
264                                 text_interval = frame_seconds;
265                         else
266                         if(frame_seconds * 2 >= min_time)
267                                 text_interval = frame_seconds * 2;
268                         else
269                         if(frame_seconds * 5 >= min_time)
270                                 text_interval = frame_seconds * 5;
271                         else
272                         {
274                                 for(int factor = 10, progression = 0; factor <= 100000; )
275                                 {
276                                         if(frame_seconds * factor >= min_time)
277                                         {
278                                                 text_interval = frame_seconds * factor;
279                                                 break;
280                                         }
282                                         if(progression == 0)
283                                         {
284                                                 factor = (int)(factor * 2.5);
285                                                 progression++;
286                                         }
287                                         else
288                                         if(progression == 1)
289                                         {
290                                                 factor = (int)(factor * 2);
291                                                 progression++;
292                                         }
293                                         else
294                                         if(progression == 2)
295                                         {
296                                                 factor = (int)(factor * 2);
297                                                 progression = 0;
298                                         }
299                                 }
301                         }
302                         break;
304                 default:
305                         break;
306         }
308 // Sanity
309         while(text_interval < min_time)
310         {
311                 text_interval *= 2;
312         }
314 // Set tick interval
315         tick_interval = text_interval;
317         switch(mwindow->edl->session->time_format)
318         {
319                 case TIME_HMSF:
320                 case TIME_FEET_FRAMES:
321                 case TIME_FRAMES:
322                         if(frame_seconds / time_per_pixel > TICK_SPACING)
323                                 tick_interval = frame_seconds;
324                         break;
325         }
327 // Get first text mark on or before window start
328         starting_mark = (int64_t)((double)mwindow->edl->local_session->view_start * 
329                 time_per_pixel / text_interval);
331         double start_position = (double)starting_mark * text_interval;
332         int64_t iteration = 0;
335 //printf("text_interval=%f\n", text_interval);
336         while(start_position + text_interval * iteration < view_end)
337         {
338                 double position1 = start_position + text_interval * iteration;
339                 int pixel = (int64_t)(position1 / time_per_pixel) - 
340                         mwindow->edl->local_session->view_start;
341                 int pixel1 = pixel;
343                 Units::totext(string, 
344                         position1, 
345                         mwindow->edl->session->time_format, 
346                         sample_rate, 
347                         mwindow->edl->session->frame_rate,
348                         mwindow->edl->session->frames_per_foot);
349                 set_color(get_resources()->default_text_color);
350                 set_font(MEDIUMFONT);
352                 draw_text(pixel + TEXT_MARGIN, get_text_ascent(MEDIUMFONT), string);
353                 draw_line(pixel, LINE_MARGIN, pixel, get_h() - 2);
355                 double position2 = start_position + text_interval * (iteration + 1);
356                 int pixel2 = (int64_t)(position2 / time_per_pixel) - 
357                         mwindow->edl->local_session->view_start;
359                 for(double tick_position = position1; 
360                         tick_position < position2; 
361                         tick_position += tick_interval)
362                 {
363                         pixel = (int64_t)(tick_position / time_per_pixel) - 
364                                 mwindow->edl->local_session->view_start;
365                         if(labs(pixel - pixel1) > 1 &&
366                                 labs(pixel - pixel2) > 1)
367                                 draw_line(pixel, TICK_MARGIN, pixel, get_h() - 2);
368                 }
369                 iteration++;
370         }
375 void MTimeBar::draw_range()
377         int x1 = 0, x2 = 0;
378         if(mwindow->edl->tracks->total_playable_vtracks() &&
379                 mwindow->preferences->use_brender)
380         {
381                 double time_per_pixel = (double)mwindow->edl->local_session->zoom_sample /
382                         mwindow->edl->session->sample_rate;
383                 x1 = (int)(mwindow->edl->session->brender_start / time_per_pixel) - 
384                         mwindow->edl->local_session->view_start;
385                 x2 = (int)(mwindow->session->brender_end / time_per_pixel) - 
386                         mwindow->edl->local_session->view_start;
387         }
389         if(x2 > x1 && 
390                 x1 < get_w() && 
391                 x2 > 0)
392         {
393                 draw_top_background(get_parent(), 0, 0, x1, get_h());
395                 draw_3segmenth(x1, 0, x2 - x1, mwindow->theme->get_image("timebar_brender"));
397                 draw_top_background(get_parent(), x2, 0, get_w() - x2, get_h());
398         }
399         else
400                 draw_top_background(get_parent(), 0, 0, get_w(), get_h());
401 //printf("MTimeBar::draw_range %f %f\n", mwindow->session->brender_end, time_per_pixel);
404 void MTimeBar::select_label(double position)
406         EDL *edl = mwindow->edl;
408         mwindow->gui->unlock_window();
409         mwindow->gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
410         mwindow->gui->lock_window();
412         position = mwindow->edl->align_to_frame(position, 1);
414         if(shift_down())
415         {
416                 if(position > edl->local_session->get_selectionend(1) / 2 + 
417                         edl->local_session->get_selectionstart(1) / 2)
418                 {
419                 
420                         edl->local_session->set_selectionend(position);
421                 }
422                 else
423                 {
424                         edl->local_session->set_selectionstart(position);
425                 }
426         }
427         else
428         {
429                 edl->local_session->set_selectionstart(position);
430                 edl->local_session->set_selectionend(position);
431         }
433 // Que the CWindow
434         mwindow->cwindow->update(1, 0, 0, 0, 1);
435         mwindow->gui->cursor->hide(0);
436         mwindow->gui->cursor->draw(1);
437         mwindow->gui->canvas->activate();
438         mwindow->gui->zoombar->update();
439         mwindow->gui->patchbay->update();
440         mwindow->update_plugin_guis();
441         update_highlights();
442         mwindow->gui->canvas->flash();
446 int MTimeBar::resize_event()
448         reposition_window(mwindow->theme->mtimebar_x,
449                 mwindow->theme->mtimebar_y,
450                 mwindow->theme->mtimebar_w,
451                 mwindow->theme->mtimebar_h);
452         update();
453         return 1;
456 int MTimeBar::test_preview(int buttonpress)
458         int result = 0;
459         return result;
473 //      Local Variables:
474 //      mode: C++
475 //      c-file-style: "linux"
476 //      End: