Fly my pretties!
[ardour.git] / gtk2_ardour / editor_hscroller.cc
1 /*
2     Copyright (C) 2002 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include "editor.h"
22
23 #include <ardour/session.h>
24
25 using namespace std;
26 using namespace ARDOUR;
27
28 void
29 Editor::hscroll_slider_allocate (GtkAllocation *alloc)
30 {
31         //edit_hscroll_slider_width = alloc->width;
32         //edit_hscroll_slider_height = alloc->height ;
33
34         if (session) {
35                 track_canvas_scroller.get_hadjustment()->set_upper (session->current_end_frame() / frames_per_unit);
36         }
37
38 }
39
40 gint
41 Editor::hscroll_slider_expose (GdkEventExpose *ev)
42 {
43         GdkRectangle draw_rect;
44         GdkRectangle bar_rect;
45         gint bar_max = edit_hscroll_slider_width - 2;
46
47         bar_rect.y = 1;
48         bar_rect.height = edit_hscroll_slider_height - 2;
49
50         if (session) {
51                 bar_rect.width = (gint) floor (bar_max * ((canvas_width * frames_per_unit) / session->current_end_frame()));
52
53                 if (bar_rect.width > bar_max) {
54                         bar_rect.x = 1;
55                         bar_rect.width = bar_max;
56                 } else {
57                         bar_rect.x = 1 + (gint) floor (bar_max * ((double) leftmost_frame / session->current_end_frame()));
58                 }
59                 
60         } else {
61                 bar_rect.x = 1;
62                 bar_rect.width = bar_max;
63         }
64
65         /* make sure we can see the bar at all times, and have enough to do zoom-trim on */
66
67         bar_rect.width = max ((guint16) (edit_hscroll_edge_width+5), bar_rect.width);
68
69         gdk_rectangle_intersect (&ev->area, &bar_rect, &draw_rect);
70
71         gtk_paint_box (edit_hscroll_slider.get_style()->gobj(),
72                        edit_hscroll_slider.get_window(),
73                        GTK_STATE_ACTIVE, 
74                        Gtk::SHADOW_IN, 
75                        &ev->area, 
76                        GTK_WIDGET(edit_hscroll_slider.gobj()),
77                        "trough",
78                        0, 0, -1, -1);
79
80         gtk_paint_box (edit_hscroll_slider.get_style()->gobj(),
81                        edit_hscroll_slider.get_window(),
82                        Gtk::STATE_NORMAL, 
83                        Gtk::SHADOW_OUT, 
84                        &draw_rect,
85                        GTK_WIDGET(edit_hscroll_slider.gobj()),
86                        "hscale",
87                        bar_rect.x, bar_rect.y, bar_rect.width, bar_rect.height);
88
89
90         return TRUE;
91 }
92
93 gint
94 Editor::hscroll_slider_button_press (GdkEventButton *ev)
95 {
96         if (!session) {
97                 return TRUE;
98         }
99
100         edit_hscroll_dragging = true;
101         //cerr << "PRESS" << endl;
102
103         return TRUE;
104         
105         gint start;
106         gint width;
107         gint end;
108         gint x;
109
110         start = (gint) floor (edit_hscroll_slider_width * ((double) leftmost_frame / session->current_end_frame()));
111         width = (gint) floor (edit_hscroll_slider_width * ((canvas_width * frames_per_unit) / session->current_end_frame()));
112
113         end = start + width - 1;
114         x = (gint) max (0.0, ev->x);
115         
116         if (x >= start && x <= end) {
117                 
118                 edit_hscroll_drag_last = x;
119                 edit_hscroll_dragging = true;
120                 Gtk::Main::grab_add (edit_hscroll_slider);
121         }
122
123         return TRUE;
124 }
125
126 gint
127 Editor::hscroll_slider_button_release (GdkEventButton *ev)
128 {
129         if (!session) {
130                 return TRUE;
131         }
132
133         gint start;
134         gint width;
135         gint end;
136         gint x;
137         gint bar_max = edit_hscroll_slider_width - 2;
138         jack_nframes_t new_leftmost = 0;
139
140         //cerr << "RELESAE" << endl;
141
142         if (edit_hscroll_dragging) {
143                 // lets do a tempo redisplay now only, because it is dog slow
144                 tempo_map_changed (Change (0));
145                 edit_hscroll_dragging = false;
146         }
147         
148         return TRUE;
149
150         
151         start = (gint) floor (bar_max * ((double) leftmost_frame / session->current_end_frame()));
152         width = (gint) floor (bar_max * ((canvas_width * frames_per_unit) / session->current_end_frame()));
153
154         end = start + width - 1;
155         x = (gint) max (0.0, ev->x);
156
157         if (!edit_hscroll_dragging) {
158
159                 new_leftmost = (jack_nframes_t) floor (((double) x/bar_max) * session->current_end_frame());
160                 reposition_x_origin (new_leftmost);
161         }
162
163         if (edit_hscroll_dragging) {
164                 // lets do a tempo redisplay now only, because it is dog slow
165                 tempo_map_changed (Change (0));
166                 edit_hscroll_dragging = false;
167                 Gtk::Main::grab_remove (edit_hscroll_slider);
168         } 
169
170         return TRUE;
171 }
172
173 gint
174 Editor::hscroll_slider_motion (GdkEventMotion *ev)
175 {
176         gint x, y;
177         GdkModifierType state;
178         gint bar_max = edit_hscroll_slider_width - 2;
179
180         if (!session || !edit_hscroll_dragging) {
181                 return TRUE;
182         }
183
184         edit_hscroll_slider.get_window().get_pointer (x, y, state);
185
186         jack_nframes_t new_frame;
187         jack_nframes_t frames;
188         double distance;
189         double fract;
190
191         distance = x - edit_hscroll_drag_last;
192         fract = fabs (distance) / bar_max;
193         frames = (jack_nframes_t) floor (session->current_end_frame() * fract);
194
195         if (distance < 0) {
196                 if (leftmost_frame < frames) {
197                         new_frame = 0;
198                 } else {
199                         new_frame = leftmost_frame - frames;
200                 }
201         } else {
202                 if (leftmost_frame > max_frames - frames) {
203                         new_frame = max_frames;
204                 } else {
205                         new_frame = leftmost_frame + frames;
206                 }
207         }
208
209         if (new_frame != leftmost_frame) {
210                 reposition_x_origin (new_frame);
211         }
212
213         edit_hscroll_drag_last = x;
214         
215         return TRUE;
216 }
217
218 void
219 Editor::update_hscroller ()
220 {
221         //edit_hscroll_slider.queue_draw ();
222 //      if (session) {
223 //              track_canvas_scroller.get_hadjustment()->set_upper (session->current_end_frame() / frames_per_unit);
224 //              track_canvas_scroller.get_hadjustment()->set_value (leftmost_frame/frames_per_unit);
225 //      }
226 }
227
228 gint
229 Editor::hscroll_left_arrow_button_press (GdkEventButton *ev)
230 {
231         if (!session) {
232                 return FALSE;
233         }
234
235         start_canvas_autoscroll (-1);
236         return TRUE;
237 }
238
239 gint
240 Editor::hscroll_right_arrow_button_press (GdkEventButton *ev)
241 {
242         if (!session) {
243                 return FALSE;
244         }
245
246         start_canvas_autoscroll (1);
247         return TRUE;
248 }
249
250 gint
251 Editor::hscroll_left_arrow_button_release (GdkEventButton *ev)
252 {
253         if (!session) {
254                 return FALSE;
255         }
256
257         stop_canvas_autoscroll ();
258         return TRUE;
259 }
260
261 gint
262 Editor::hscroll_right_arrow_button_release (GdkEventButton *ev)
263 {
264         if (!session) {
265                 return FALSE;
266         }
267
268         stop_canvas_autoscroll ();
269         return TRUE;
270 }