fix keyboard event handling for host-provided plugin GUIs
[ardour2.git] / gtk2_ardour / ardour_ui_dialogs.cc
blobd4c4ce81132e0411ccbf71e2aee97bd939ee26da
1 /*
2 Copyright (C) 2000 Paul Davis
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.
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.
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.
20 /* This file contains any ARDOUR_UI methods that require knowledge of
21 the various dialog boxes, and exists so that no compilation dependency
22 exists between the main ARDOUR_UI modules and their respective classes.
23 This is to cut down on the compile times. It also helps with my sanity.
26 #include <ardour/session.h>
28 #include "actions.h"
29 #include "ardour_ui.h"
30 #include "connection_editor.h"
31 #include "location_ui.h"
32 #include "mixer_ui.h"
33 #include "option_editor.h"
34 #include "public_editor.h"
35 #include "route_params_ui.h"
36 #include "sfdb_ui.h"
37 #include "theme_manager.h"
38 #include "keyeditor.h"
40 #include "i18n.h"
42 using namespace ARDOUR;
43 using namespace PBD;
44 using namespace Glib;
45 using namespace Gtk;
46 using namespace Gtkmm2ext;
48 void
49 ARDOUR_UI::connect_to_session (Session *s)
51 session = s;
53 session->Xrun.connect (mem_fun(*this, &ARDOUR_UI::xrun_handler));
54 session->RecordStateChanged.connect (mem_fun (*this, &ARDOUR_UI::record_state_changed));
56 /* sensitize menu bar options that are now valid */
58 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
59 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, session->writable());
61 if (session->locations()->num_range_markers()) {
62 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
63 } else {
64 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
67 if (!session->control_out()) {
68 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
69 if (act) {
70 act->set_sensitive (false);
74 /* allow wastebasket flush again */
76 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
77 if (act) {
78 act->set_sensitive (true);
81 /* there are never any selections on startup */
83 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
84 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
85 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
86 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
87 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
89 session->locations()->added.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
90 session->locations()->removed.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
92 rec_button.set_sensitive (true);
93 shuttle_box.set_sensitive (true);
95 if (connection_editor) {
96 connection_editor->set_session (s);
99 if (location_ui) {
100 location_ui->set_session(s);
103 if (route_params) {
104 route_params->set_session (s);
107 if (option_editor) {
108 option_editor->set_session (s);
111 setup_session_options ();
113 Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
114 Blink.connect (mem_fun(*this, &ARDOUR_UI::solo_blink));
115 Blink.connect (mem_fun(*this, &ARDOUR_UI::audition_blink));
117 /* these are all need to be handled in an RT-safe and MT way, so don't
118 do any GUI work, just queue it for handling by the GUI thread.
121 session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::queue_transport_change));
123 /* alert the user to these things happening */
125 session->AuditionActive.connect (mem_fun(*this, &ARDOUR_UI::auditioning_changed));
126 session->SoloActive.connect (mem_fun(*this, &ARDOUR_UI::soloing_changed));
128 solo_alert_button.set_active (session->soloing());
130 /* update autochange callback on dirty state changing */
132 session->DirtyChanged.connect (mem_fun(*this, &ARDOUR_UI::update_autosave));
134 /* can't be auditioning here */
136 primary_clock.set_session (s);
137 secondary_clock.set_session (s);
138 big_clock.set_session (s);
139 preroll_clock.set_session (s);
140 postroll_clock.set_session (s);
142 /* Clocks are on by default after we are connected to a session, so show that here.
145 connect_dependents_to_session (s);
147 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
148 restore their modes or are explicitly set, we will cause the "new" mode to be saved
149 back to the session XML ("extra") state.
152 AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
154 Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
156 start_clocking ();
157 start_blinking ();
159 map_transport_state ();
161 second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
162 point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
163 point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
167 ARDOUR_UI::unload_session (bool hide_stuff)
169 if (session && session->dirty()) {
170 switch (ask_about_saving_session (_("close"))) {
171 case -1:
172 return 1;
174 case 1:
175 session->save_state ("");
176 break;
180 if (hide_stuff) {
181 editor->hide ();
182 mixer->hide ();
183 theme_manager->hide ();
186 second_connection.disconnect ();
187 point_one_second_connection.disconnect ();
188 point_oh_five_second_connection.disconnect ();
189 point_zero_one_second_connection.disconnect();
191 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
193 rec_button.set_sensitive (false);
194 shuttle_box.set_sensitive (false);
196 stop_blinking ();
197 stop_clocking ();
199 /* drop everything attached to the blink signal */
201 Blink.clear ();
203 primary_clock.set_session (0);
204 secondary_clock.set_session (0);
205 big_clock.set_session (0);
206 preroll_clock.set_session (0);
207 postroll_clock.set_session (0);
209 if (option_editor) {
210 option_editor->set_session (0);
213 if (mixer) {
214 mixer->hide_all ();
217 delete session;
218 session = 0;
220 update_buffer_load ();
222 return 0;
226 ARDOUR_UI::create_connection_editor ()
228 #if 0
229 if (connection_editor == 0) {
230 connection_editor = new ConnectionEditor ();
231 connection_editor->signal_unmap().connect (sigc::bind (ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleConnections")));
234 if (session) {
235 connection_editor->set_session (session);
237 #endif
239 return 0;
242 void
243 ARDOUR_UI::toggle_connection_editor ()
245 if (create_connection_editor()) {
246 return;
249 #if 0
250 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleConnections"));
251 if (act) {
252 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
254 if (tact->get_active()) {
255 connection_editor->show_all ();
256 connection_editor->present ();
257 } else {
258 connection_editor->hide ();
261 #endif
264 void
265 ARDOUR_UI::toggle_big_clock_window ()
267 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
268 if (act) {
269 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
271 if (tact->get_active()) {
272 big_clock_window->show_all ();
273 big_clock_window->present ();
274 } else {
275 big_clock_window->hide ();
280 void
281 ARDOUR_UI::toggle_options_window ()
283 if (option_editor == 0) {
284 option_editor = new OptionEditor (*this, *editor, *mixer);
285 option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleOptionsEditor")));
286 option_editor->set_session (session);
289 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleOptionsEditor"));
290 if (act) {
291 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
293 if (tact->get_active()) {
294 option_editor->show_all ();
295 option_editor->present ();
296 } else {
297 option_editor->hide ();
303 ARDOUR_UI::create_location_ui ()
305 if (location_ui == 0) {
306 location_ui = new LocationUI ();
307 location_ui->set_session (session);
308 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
310 return 0;
313 void
314 ARDOUR_UI::toggle_location_window ()
316 if (create_location_ui()) {
317 return;
320 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
321 if (act) {
322 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
324 if (tact->get_active()) {
325 location_ui->show_all ();
326 location_ui->present ();
327 } else {
328 location_ui->hide ();
333 void
334 ARDOUR_UI::toggle_key_editor ()
336 if (key_editor == 0) {
337 key_editor = new KeyEditor;
338 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
341 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
342 if (act) {
343 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
345 if (tact->get_active()) {
346 key_editor->show_all ();
347 key_editor->present ();
348 } else {
349 key_editor->hide ();
354 void
355 ARDOUR_UI::toggle_theme_manager ()
357 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
358 if (act) {
359 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
361 if (tact->get_active()) {
362 theme_manager->show_all ();
363 theme_manager->present ();
364 } else {
365 theme_manager->hide ();
371 ARDOUR_UI::create_route_params ()
373 if (route_params == 0) {
374 route_params = new RouteParams_UI ();
375 route_params->set_session (session);
376 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
378 return 0;
381 void
382 ARDOUR_UI::toggle_route_params_window ()
384 if (create_route_params ()) {
385 return;
388 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
389 if (act) {
390 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
392 if (tact->get_active()) {
393 route_params->show_all ();
394 route_params->present ();
395 } else {
396 route_params->hide ();
401 void
402 ARDOUR_UI::handle_locations_change (Location* ignored)
404 if (session) {
405 if (session->locations()->num_range_markers()) {
406 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
407 } else {
408 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
413 bool
414 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
416 if (window_was_editor) {
418 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
419 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
420 float_big_clock (editor);
423 } else {
425 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
426 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
427 float_big_clock (mixer);
431 return false;