merge from 2.0-ongoing by hand, minus key binding editor
[ardour.git] / gtk2_ardour / editor_keyboard.cc
1 /*
2     Copyright (C) 2004 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 */
19
20 #include <ardour/audioregion.h>
21 #include <ardour/playlist.h>
22 #include <pbd/memento_command.h>
23
24 #include "editor.h"
25 #include "region_view.h"
26 #include "selection.h"
27
28 #include "i18n.h"
29
30 void
31 Editor::kbd_driver (sigc::slot<void,GdkEvent*> theslot, bool use_track_canvas, bool use_time_canvas, bool can_select)
32 {
33         gint x, y;
34         double worldx, worldy;
35         GdkEvent ev;
36         Gdk::ModifierType mask;
37         Glib::RefPtr<Gdk::Window> evw = track_canvas.get_window()->get_pointer (x, y, mask);
38         bool doit = false;
39
40         if (use_track_canvas && track_canvas_event_box.get_window()->get_pointer(x, y, mask) != 0) {
41                 doit = true;
42         } else if (use_time_canvas && time_canvas_event_box.get_window()->get_pointer(x, y, mask)!= 0) {
43                 doit = true;
44         }
45
46         /* any use of "keyboard mouse buttons" invalidates an existing grab
47         */
48         
49         if (drag_info.item) {
50                 drag_info.item->ungrab (GDK_CURRENT_TIME);
51                 drag_info.item = 0;
52         }
53
54         if (doit) {
55
56                 if (entered_regionview && can_select) {
57                         selection->set (entered_regionview);
58                 }
59
60                 track_canvas.window_to_world (x, y, worldx, worldy);
61                 worldx += horizontal_adjustment.get_value();
62                 worldy += vertical_adjustment.get_value();
63
64                 ev.type = GDK_BUTTON_PRESS;
65                 ev.button.x = worldx;
66                 ev.button.y = worldy;
67                 ev.button.state = 0;  /* XXX correct? */
68
69                 theslot (&ev);
70         }
71 }
72
73 void
74 Editor::kbd_set_playhead_cursor ()
75 {
76         kbd_driver (mem_fun(*this, &Editor::set_playhead_cursor), true, true, false);
77 }
78
79 void
80 Editor::kbd_set_edit_cursor ()
81 {
82         kbd_driver (mem_fun(*this, &Editor::set_edit_cursor), true, true, false);
83 }
84
85
86 void
87 Editor::kbd_do_split (GdkEvent* ev)
88 {
89         nframes_t where = event_frame (ev);
90
91         if (entered_regionview) {
92                 if (selection->regions.contains (entered_regionview)) {
93                         split_regions_at (where, selection->regions);
94                 } else {
95                         RegionSelection s;
96
97                         /* add equivalent regions to the selection that we'll split */
98                         vector<RegionView*> eq;
99                         get_equivalent_regions (entered_regionview, eq);
100                         for (vector<RegionView*>::iterator i = eq.begin(); i != eq.end(); ++i) {
101                                 s.add (*i);
102                         }
103                         
104                         split_regions_at (where, s);
105                 }
106         }
107 }
108
109 void
110 Editor::kbd_split ()
111 {
112         kbd_driver (mem_fun(*this, &Editor::kbd_do_split), true, true, false);
113 }
114
115 void
116 Editor::kbd_mute_unmute_region ()
117 {
118         if (entered_regionview) {
119                 begin_reversible_command (_("mute region"));
120                 XMLNode &before = entered_regionview->region()->playlist()->get_state();
121                 
122                 entered_regionview->region()->set_muted (!entered_regionview->region()->muted());
123                 
124                 XMLNode &after = entered_regionview->region()->playlist()->get_state();
125                 session->add_command (new MementoCommand<ARDOUR::Playlist>(*(entered_regionview->region()->playlist()), &before, &after));
126                 commit_reversible_command();
127         }
128 }
129
130 void
131 Editor::kbd_set_sync_position ()
132 {
133         kbd_driver (mem_fun(*this, &Editor::kbd_do_set_sync_position), true, true, false);
134 }
135
136 void
137 Editor::kbd_do_set_sync_position (GdkEvent* ev)
138 {
139     nframes_t where = event_frame (ev);
140         snap_to (where);
141
142         if (entered_regionview) {
143           set_a_regions_sync_position (entered_regionview->region(), where);
144         }
145 }
146
147 void
148 Editor::kbd_do_align (GdkEvent* ev, ARDOUR::RegionPoint what)
149 {
150         align (what);
151 }
152
153 void
154 Editor::kbd_align (ARDOUR::RegionPoint what)
155 {
156         kbd_driver (bind (mem_fun(*this, &Editor::kbd_do_align), what));
157 }
158
159 void
160 Editor::kbd_do_align_relative (GdkEvent* ev, ARDOUR::RegionPoint what)
161 {
162         align (what);
163 }
164
165 void
166 Editor::kbd_align_relative (ARDOUR::RegionPoint what)
167 {
168         kbd_driver (bind (mem_fun(*this, &Editor::kbd_do_align), what), true, true, false);
169 }
170
171 void
172 Editor::kbd_do_brush (GdkEvent *ev)
173 {
174         brush (event_frame (ev, 0, 0));
175 }
176
177 void
178 Editor::kbd_brush ()
179 {
180         kbd_driver (mem_fun(*this, &Editor::kbd_do_brush), true, true, false);
181 }
182
183 void
184 Editor::kbd_do_audition (GdkEvent *ignored)
185 {
186         audition_selected_region ();
187 }
188
189 void
190 Editor::kbd_audition ()
191 {
192         kbd_driver (mem_fun(*this, &Editor::kbd_do_audition), true, false, true);
193 }