From f0748535a5023d132eff03999a705a3e56c516db Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 19 Mar 2010 02:49:01 +0000 Subject: save tearoff state; restore monitor section state reasonably well; fixup access control to parts of editor.h (needs more work); extend CrossThread just a little git-svn-id: svn://localhost/ardour2/branches/3.0@6774 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour_ui.cc | 76 ++----------------- gtk2_ardour/ardour_ui_dependents.cc | 1 + gtk2_ardour/ardour_ui_ed.cc | 97 +++++++++++++++++++++++- gtk2_ardour/editor.cc | 82 +++++++++------------ gtk2_ardour/editor.h | 29 +++++--- gtk2_ardour/level_meter.h | 1 + gtk2_ardour/mixer_ui.cc | 43 ++++++++--- gtk2_ardour/mixer_ui.h | 4 +- gtk2_ardour/monitor_section.cc | 92 +++++++++++++++++++---- gtk2_ardour/monitor_section.h | 4 + gtk2_ardour/public_editor.h | 7 ++ libs/gtkmm2ext/gtkmm2ext/tearoff.h | 14 ++++ libs/gtkmm2ext/tearoff.cc | 142 +++++++++++++++++++++++++++++++----- libs/pbd/crossthread.cc | 12 +++ libs/pbd/pbd/crossthread.h | 3 + 15 files changed, 432 insertions(+), 175 deletions(-) diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 786e14aa69..b216acae29 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -404,7 +404,7 @@ ARDOUR_UI::post_engine () /* start the time-of-day-clock */ #ifndef GTKOSX - /* OS X provides an always visible wallclock, so don't be stupid */ + /* OS X provides a nearly-always visible wallclock, so don't be stupid */ update_wall_clock (); Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000); #endif @@ -431,8 +431,6 @@ ARDOUR_UI::post_engine () ARDOUR_UI::~ARDOUR_UI () { - save_ardour_state (); - delete keyboard; delete editor; delete mixer; @@ -453,18 +451,19 @@ ARDOUR_UI::configure_timeout () { if (last_configure_time == 0) { /* no configure events yet */ - return TRUE; + return true; } /* force a gap of 0.5 seconds since the last configure event */ if (get_microseconds() - last_configure_time < 500000) { - return TRUE; + return true; } else { have_configure_timeout = false; + cerr << "config event-driven save\n"; save_ardour_state (); - return FALSE; + return false; } } @@ -538,67 +537,6 @@ ARDOUR_UI::get_transport_controllable_state () return *node; } -void -ARDOUR_UI::save_ardour_state () -{ - if (!keyboard || !mixer || !editor) { - return; - } - - /* XXX this is all a bit dubious. add_extra_xml() uses - a different lifetime model from add_instant_xml(). - */ - - XMLNode* node = new XMLNode (keyboard->get_state()); - Config->add_extra_xml (*node); - Config->add_extra_xml (get_transport_controllable_state()); - - XMLNode* window_node = new XMLNode (X_("UI")); - - window_node->add_property ("show-big-clock", (big_clock_window && big_clock_window->is_visible() ? "yes" : "no")); - - Glib::RefPtr win; - - if (big_clock_window && (win = big_clock_window->get_window())) { - - int w, h; - int xoff, yoff; - char buf[32]; - - win->get_size (w, h); - win->get_position (xoff, yoff); - - snprintf (buf, sizeof (buf), "%d", w); - window_node->add_property ("big-clock-x-size", buf); - snprintf (buf, sizeof (buf), "%d", h); - window_node->add_property ("big-clock-y-size", buf); - snprintf (buf, sizeof (buf), "%d", xoff); - window_node->add_property ("big-clock-x-off", buf); - snprintf (buf, sizeof (buf), "%d", yoff); - window_node->add_property ("big-clock-y-off", buf); - } - - Config->add_extra_xml (*window_node); - - if (_startup && _startup->engine_control() && _startup->engine_control()->was_used()) { - Config->add_extra_xml (_startup->engine_control()->get_state()); - } - Config->save_state(); - ui_config->save_state (); - - XMLNode enode(static_cast(editor)->get_state()); - XMLNode mnode(mixer->get_state()); - - if (_session) { - _session->add_instant_xml (enode); - _session->add_instant_xml (mnode); - } else { - Config->add_instant_xml (enode); - Config->add_instant_xml (mnode); - } - - Keyboard::save_keybindings (); -} gint ARDOUR_UI::autosave_session () @@ -831,6 +769,7 @@ If you still wish to quit, please use the\n\n\ ArdourDialog::close_all_dialogs (); engine->stop (true); + cerr << "Save before quit\n"; save_ardour_state (); quit (); } @@ -2091,7 +2030,7 @@ ARDOUR_UI::snapshot_session () void ARDOUR_UI::save_state (const string & name) { - (void) save_state_canfail (name); + save_state_canfail (name); } int @@ -2108,6 +2047,7 @@ ARDOUR_UI::save_state_canfail (string name) return ret; } } + cerr << "SS canfail\n"; save_ardour_state (); /* XXX cannot fail? yeah, right ... */ return 0; } diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc index 6f48bee04b..fb5757a809 100644 --- a/gtk2_ardour/ardour_ui_dependents.cc +++ b/gtk2_ardour/ardour_ui_dependents.cc @@ -130,3 +130,4 @@ ARDOUR_UI::exit_on_main_window_close (GdkEventAny * /*ev*/) return TRUE; #endif } + diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 9630c37fae..46cd5d952d 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -26,11 +26,12 @@ #include #include - -#include -#include #include +#include "gtkmm2ext/utils.h" +#include "gtkmm2ext/window_title.h" +#include "gtkmm2ext/tearoff.h" + #include "pbd/file_utils.h" #include "pbd/fpu.h" #include "pbd/convert.h" @@ -38,10 +39,13 @@ #include "ardour_ui.h" #include "public_editor.h" #include "audio_clock.h" +#include "keyboard.h" +#include "monitor_section.h" #include "engine_dialog.h" #include "editor.h" #include "actions.h" #include "mixer_ui.h" +#include "startup.h" #include "utils.h" #ifdef GTKOSX @@ -671,3 +675,90 @@ ARDOUR_UI::idle_big_clock_text_resizer (int win_w, int win_h) return false; } + +void +ARDOUR_UI::save_ardour_state () +{ + if (!keyboard || !mixer || !editor) { + return; + } + + /* XXX this is all a bit dubious. add_extra_xml() uses + a different lifetime model from add_instant_xml(). + */ + + XMLNode* node = new XMLNode (keyboard->get_state()); + Config->add_extra_xml (*node); + Config->add_extra_xml (get_transport_controllable_state()); + + XMLNode* window_node = new XMLNode (X_("UI")); + + window_node->add_property ("show-big-clock", (big_clock_window && big_clock_window->is_visible() ? "yes" : "no")); + + Glib::RefPtr win; + + if (big_clock_window && (win = big_clock_window->get_window())) { + + int w, h; + int xoff, yoff; + char buf[32]; + + win->get_size (w, h); + win->get_position (xoff, yoff); + + snprintf (buf, sizeof (buf), "%d", w); + window_node->add_property ("big-clock-x-size", buf); + snprintf (buf, sizeof (buf), "%d", h); + window_node->add_property ("big-clock-y-size", buf); + snprintf (buf, sizeof (buf), "%d", xoff); + window_node->add_property ("big-clock-x-off", buf); + snprintf (buf, sizeof (buf), "%d", yoff); + window_node->add_property ("big-clock-y-off", buf); + } + + /* tearoffs */ + + XMLNode* tearoff_node = new XMLNode (X_("Tearoffs")); + + if (transport_tearoff) { + XMLNode* t = new XMLNode (X_("transport")); + transport_tearoff->add_tornoff_state (*t); + tearoff_node->add_child_nocopy (*t); + } + + if (mixer && mixer->monitor_section()) { + XMLNode* t = new XMLNode (X_("monitor-section")); + mixer->monitor_section()->tearoff()->add_tornoff_state (*t); + tearoff_node->add_child_nocopy (*t); + } + + if (editor && editor->mouse_mode_tearoff()) { + XMLNode* t = new XMLNode (X_("mouse-mode")); + editor->mouse_mode_tearoff ()->add_tornoff_state (*t); + tearoff_node->add_child_nocopy (*t); + } + + window_node->add_child_nocopy (*tearoff_node); + + Config->add_extra_xml (*window_node); + + if (_startup && _startup->engine_control() && _startup->engine_control()->was_used()) { + Config->add_extra_xml (_startup->engine_control()->get_state()); + } + Config->save_state(); + ui_config->save_state (); + + XMLNode enode(static_cast(editor)->get_state()); + XMLNode mnode(mixer->get_state()); + + if (_session) { + _session->add_instant_xml (enode); + _session->add_instant_xml (mnode); + } else { + Config->add_instant_xml (enode); + Config->add_instant_xml (mnode); + } + + Keyboard::save_keybindings (); +} + diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 572e192357..5d47554f08 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2802,22 +2802,22 @@ Editor::setup_toolbar () mode_box->pack_start (edit_mode_selector); mode_box->pack_start (*mouse_mode_button_box); - mouse_mode_tearoff = manage (new TearOff (*mode_box)); - mouse_mode_tearoff->set_name ("MouseModeBase"); - mouse_mode_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), &mouse_mode_tearoff->tearoff_window()), false); + _mouse_mode_tearoff = manage (new TearOff (*mode_box)); + _mouse_mode_tearoff->set_name ("MouseModeBase"); + _mouse_mode_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), &_mouse_mode_tearoff->tearoff_window()), false); if (Profile->get_sae()) { - mouse_mode_tearoff->set_can_be_torn_off (false); + _mouse_mode_tearoff->set_can_be_torn_off (false); } - mouse_mode_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), - &mouse_mode_tearoff->tearoff_window())); - mouse_mode_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), - &mouse_mode_tearoff->tearoff_window(), 1)); - mouse_mode_tearoff->Hidden.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), - &mouse_mode_tearoff->tearoff_window())); - mouse_mode_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), - &mouse_mode_tearoff->tearoff_window(), 1)); + _mouse_mode_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), + &_mouse_mode_tearoff->tearoff_window())); + _mouse_mode_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), + &_mouse_mode_tearoff->tearoff_window(), 1)); + _mouse_mode_tearoff->Hidden.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), + &_mouse_mode_tearoff->tearoff_window())); + _mouse_mode_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), + &_mouse_mode_tearoff->tearoff_window(), 1)); mouse_move_button.set_mode (false); mouse_select_button.set_mode (false); @@ -2931,28 +2931,28 @@ Editor::setup_toolbar () HBox* hbox = manage (new HBox); hbox->set_spacing(10); - tools_tearoff = manage (new TearOff (*hbox)); - tools_tearoff->set_name ("MouseModeBase"); - tools_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), &tools_tearoff->tearoff_window()), false); - + _tools_tearoff = manage (new TearOff (*hbox)); + _tools_tearoff->set_name ("MouseModeBase"); + _tools_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), &_tools_tearoff->tearoff_window()), false); + if (Profile->get_sae()) { - tools_tearoff->set_can_be_torn_off (false); + _tools_tearoff->set_can_be_torn_off (false); } - tools_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), - &tools_tearoff->tearoff_window())); - tools_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), - &tools_tearoff->tearoff_window(), 0)); - tools_tearoff->Hidden.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), - &tools_tearoff->tearoff_window())); - tools_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), - &tools_tearoff->tearoff_window(), 0)); + _tools_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), + &_tools_tearoff->tearoff_window())); + _tools_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), + &_tools_tearoff->tearoff_window(), 0)); + _tools_tearoff->Hidden.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), + &_tools_tearoff->tearoff_window())); + _tools_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), + &_tools_tearoff->tearoff_window(), 0)); toolbar_hbox.set_spacing (10); toolbar_hbox.set_border_width (1); - toolbar_hbox.pack_start (*mouse_mode_tearoff, false, false); - toolbar_hbox.pack_start (*tools_tearoff, false, false); + toolbar_hbox.pack_start (*_mouse_mode_tearoff, false, false); + toolbar_hbox.pack_start (*_tools_tearoff, false, false); hbox->pack_start (snap_box, false, false); hbox->pack_start (*nudge_box, false, false); @@ -3660,10 +3660,7 @@ Editor::pane_allocation_handler (Allocation &alloc, Paned* which) void Editor::detach_tearoff (Box* /*b*/, Window* /*w*/) { - cerr << "remove tearoff\n"; - - if (tools_tearoff->torn_off() && - mouse_mode_tearoff->torn_off()) { + if (_tools_tearoff->torn_off() && _mouse_mode_tearoff->torn_off()) { top_hbox.remove (toolbar_frame); } } @@ -3671,7 +3668,6 @@ Editor::detach_tearoff (Box* /*b*/, Window* /*w*/) void Editor::reattach_tearoff (Box* /*b*/, Window* /*w*/, int32_t /*n*/) { - cerr << "reattach tearoff\n"; if (toolbar_frame.get_parent() == 0) { top_hbox.pack_end (toolbar_frame); } @@ -3985,8 +3981,8 @@ Editor::session_state_saved (string snap_name) void Editor::maximise_editing_space () { - mouse_mode_tearoff->set_visible (false); - tools_tearoff->set_visible (false); + _mouse_mode_tearoff->set_visible (false); + _tools_tearoff->set_visible (false); pre_maximal_pane_position = edit_pane.get_position(); pre_maximal_editor_width = this->get_width(); @@ -4016,8 +4012,8 @@ Editor::restore_editing_space () unfullscreen(); - mouse_mode_tearoff->set_visible (true); - tools_tearoff->set_visible (true); + _mouse_mode_tearoff->set_visible (true); + _tools_tearoff->set_visible (true); post_maximal_editor_width = this->get_width(); edit_pane.set_position (pre_maximal_pane_position + abs(this->get_width() - pre_maximal_editor_width)); @@ -4702,8 +4698,8 @@ Editor::first_idle () _have_idled = true; } -static gboolean -_idle_resizer (gpointer arg) +gboolean +Editor::_idle_resize (gpointer arg) { return ((Editor*)arg)->idle_resize (); } @@ -4711,10 +4707,8 @@ _idle_resizer (gpointer arg) void Editor::add_to_idle_resize (TimeAxisView* view, int32_t h) { - cerr << "add tav " << view << " with hdelta = " << h << endl; - if (resize_idle_id < 0) { - resize_idle_id = g_idle_add (_idle_resizer, this); + resize_idle_id = g_idle_add (_idle_resize, this); _pending_resize_amount = 0; } @@ -4726,8 +4720,6 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h) _pending_resize_amount += h; _pending_resize_view = view; - cerr << "Pending resize amount initially set at " << _pending_resize_amount << endl; - min_resulting = min (min_resulting, int32_t (_pending_resize_view->current_height()) + _pending_resize_amount); if (selection->tracks.contains (_pending_resize_view)) { @@ -4743,7 +4735,6 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h) /* clamp */ if (uint32_t (min_resulting) < TimeAxisView::hSmall) { _pending_resize_amount += TimeAxisView::hSmall - min_resulting; - cerr << "pending resize amount = " << _pending_resize_amount << endl; } } @@ -4751,9 +4742,6 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h) bool Editor::idle_resize () { - cerr << "Idle resize, pra = " << _pending_resize_amount - << " set height to " << _pending_resize_view->current_height() << " + " << _pending_resize_amount << endl; - _pending_resize_view->idle_resize (_pending_resize_view->current_height() + _pending_resize_amount); if (dynamic_cast (_pending_resize_view) == 0 && diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 0fc433d2fb..b2e1a38034 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -444,6 +444,15 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void center_screen (nframes64_t); TrackViewList axis_views_from_routes (boost::shared_ptr) const; + Gtkmm2ext::TearOff* mouse_mode_tearoff () const { return _mouse_mode_tearoff; } + Gtkmm2ext::TearOff* tools_tearoff () const { return _tools_tearoff; } + + void snap_to (nframes64_t& first, int32_t direction = 0, bool for_mark = false); + void snap_to_with_modifier (nframes64_t& first, GdkEvent const *, int32_t direction = 0, bool for_mark = false); + void snap_to (nframes64_t& first, nframes64_t& last, int32_t direction = 0, bool for_mark = false); + + void begin_reversible_command (std::string cmd_name); + void commit_reversible_command (); protected: void map_transport_state (); @@ -1347,8 +1356,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD private: ArdourCanvas::Item *last_item_entered; int last_item_entered_n; -public: +public: bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*); bool canvas_frame_handle_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*); bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*); @@ -1377,6 +1386,11 @@ public: bool canvas_markerview_start_handle_event(GdkEvent* event, ArdourCanvas::Item*,MarkerView*); bool canvas_markerview_end_handle_event(GdkEvent* event, ArdourCanvas::Item*,MarkerView*); + private: + friend class DragManager; + friend class EditorRouteGroups; + friend class EditorRegions; + /* non-public event handlers */ bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*); @@ -1488,10 +1502,6 @@ public: void tempo_map_changed (const PBD::PropertyChange&); void redisplay_tempo (bool immediate_redraw); - void snap_to (nframes64_t& first, int32_t direction = 0, bool for_mark = false); - void snap_to_with_modifier (nframes64_t& first, GdkEvent const *, int32_t direction = 0, bool for_mark = false); - void snap_to (nframes64_t& first, nframes64_t& last, int32_t direction = 0, bool for_mark = false); - uint32_t bbt_beat_subdivision; /* toolbar */ @@ -1515,7 +1525,7 @@ public: Gtk::Table toolbar_selection_clock_table; Gtk::Label toolbar_selection_cursor_label; - Gtkmm2ext::TearOff* mouse_mode_tearoff; + Gtkmm2ext::TearOff* _mouse_mode_tearoff; Gtk::ToggleButton mouse_select_button; Gtk::ToggleButton mouse_move_button; Gtk::ToggleButton mouse_gain_button; @@ -1578,7 +1588,7 @@ public: void setup_tooltips (); - Gtkmm2ext::TearOff* tools_tearoff; + Gtkmm2ext::TearOff* _tools_tearoff; Gtk::HBox toolbar_hbox; Gtk::EventBox toolbar_base; Gtk::Frame toolbar_frame; @@ -1766,9 +1776,6 @@ public: XMLNode *before; /* used in *_reversible_command */ - void begin_reversible_command (std::string cmd_name); - void commit_reversible_command (); - void update_title (); void update_title_s (const std::string & snapshot_name); @@ -1999,8 +2006,8 @@ public: bool _have_idled; int resize_idle_id; + static gboolean _idle_resize (gpointer); bool idle_resize(); - friend gboolean _idle_resize (gpointer); int32_t _pending_resize_amount; TimeAxisView* _pending_resize_view; diff --git a/gtk2_ardour/level_meter.h b/gtk2_ardour/level_meter.h index 06c7230b7c..6b3c33cac5 100644 --- a/gtk2_ardour/level_meter.h +++ b/gtk2_ardour/level_meter.h @@ -31,6 +31,7 @@ #include #include "ardour/types.h" +#include "ardour/chan_count.h" #include "ardour/session_handle.h" #include diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index c98d0028e9..badd96154a 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "ardour/audio_diskstream.h" @@ -67,7 +68,7 @@ Mixer_UI::Mixer_UI () { _strip_width = Config->get_default_narrow_ms() ? Narrow : Wide; track_menu = 0; - monitor_section = 0; + _monitor_section = 0; route_group_context_menu = 0; no_track_list_redisplay = false; in_group_row_change = false; @@ -321,14 +322,35 @@ Mixer_UI::add_strip (RouteList& routes) } if (route->is_control()) { - monitor_section = new MonitorSection (_session); - out_packer.pack_end (monitor_section->pack_widget(), false, false); - monitor_section->pack_widget().show_all (); - /* no regular strip */ + if (!_monitor_section) { + _monitor_section = new MonitorSection (_session); + out_packer.pack_end (_monitor_section->pack_widget(), false, false); + } else { + _monitor_section->set_session (_session); + } + + _monitor_section->pack_widget().show_all (); + + XMLNode* ui_node = Config->extra_xml(X_("UI")); + + if (ui_node) { + cerr << "Got UI node\n"; + XMLNode* tearoff_node = ui_node->child (X_("Tearoffs")); + if (tearoff_node) { + cerr << "Got tearoff node\n"; + XMLNode* mnode = tearoff_node->child (X_("monitor-section")); + if (mnode) { + cerr << "got mndeo\n"; + _monitor_section->tearoff()->set_tornoff_state (*mnode); + } + } + } + + /* no regular strip shown for control out */ + continue; } - strip = new MixerStrip (*this, _session, route); strips.push_back (strip); @@ -521,14 +543,13 @@ Mixer_UI::session_going_away () group_model->clear (); _selection.clear (); track_model->clear (); - - delete monitor_section; - monitor_section = 0; for (list::iterator i = strips.begin(); i != strips.end(); ++i) { delete (*i); } + _monitor_section->pack_widget().hide (); + strips.clear (); WindowTitle title(Glib::get_application_name()); @@ -594,8 +615,8 @@ Mixer_UI::fast_update_strips () (*i)->fast_update (); } - if (monitor_section) { - monitor_section->fast_update (); + if (_monitor_section) { + _monitor_section->fast_update (); } } } diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index 87bf57a6df..c8d3bacae0 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -81,6 +81,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR void set_auto_rebinding(bool); RouteRedirectSelection& selection() { return _selection; } + MonitorSection* monitor_section() const { return _monitor_section; } private: bool _visible; @@ -195,8 +196,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR void track_column_click (gint); void build_track_menu (); - MonitorSection* monitor_section; - + MonitorSection* _monitor_section; PluginSelector *_plugin_selector; void strip_property_changed (const PBD::PropertyChange&, MixerStrip *); diff --git a/gtk2_ardour/monitor_section.cc b/gtk2_ardour/monitor_section.cc index 8909a1649c..480786eb2c 100644 --- a/gtk2_ardour/monitor_section.cc +++ b/gtk2_ardour/monitor_section.cc @@ -61,18 +61,8 @@ MonitorSection::MonitorSection (Session* s) } - _route = _session->control_out (); - - if (!_route) { - throw failed_constructor (); - } - - _monitor = _route->monitor_control (); - - if (!_monitor) { - throw failed_constructor (); - } - + set_session (s); + VBox* sub_knob_packer = manage (new VBox); sub_knob_packer->set_spacing (12); @@ -264,6 +254,36 @@ MonitorSection::~MonitorSection () delete _tearoff; } +void +MonitorSection::set_session (Session* s) +{ + AxisView::set_session (s); + + if (_session) { + + _route = _session->control_out (); + + if (_route) { + /* session with control outs */ + _monitor = _route->monitor_control (); + meter.set_meter (&_route->peak_meter()); + } else { + /* session with no control outs */ + _monitor.reset (); + _route.reset (); + meter.set_meter (0); + } + + } else { + /* no session */ + _monitor.reset (); + _route.reset (); + meter.set_meter (0); + } + + /* both might be null */ +} + MonitorSection::ChannelButtonSet::ChannelButtonSet () : cut (X_("")) , dim (X_("")) @@ -283,6 +303,10 @@ MonitorSection::ChannelButtonSet::ChannelButtonSet () void MonitorSection::populate_buttons () { + if (!_monitor) { + return; + } + Glib::RefPtr act; uint32_t nchans = _monitor->output_streams().n_audio(); @@ -378,6 +402,10 @@ MonitorSection::pack_widget () const void MonitorSection::dim_all () { + if (!_monitor) { + return; + } + Glib::RefPtr act = ActionManager::get_action (X_("Monitor"), "monitor-dim-all"); if (act) { Glib::RefPtr tact = Glib::RefPtr::cast_dynamic(act); @@ -389,6 +417,10 @@ MonitorSection::dim_all () void MonitorSection::cut_all () { + if (!_monitor) { + return; + } + Glib::RefPtr act = ActionManager::get_action (X_("Monitor"), "monitor-cut-all"); if (act) { Glib::RefPtr tact = Glib::RefPtr::cast_dynamic(act); @@ -399,6 +431,10 @@ MonitorSection::cut_all () void MonitorSection::mono () { + if (!_monitor) { + return; + } + Glib::RefPtr act = ActionManager::get_action (X_("Monitor"), "monitor-mono"); if (act) { Glib::RefPtr tact = Glib::RefPtr::cast_dynamic(act); @@ -409,6 +445,10 @@ MonitorSection::mono () void MonitorSection::cut_channel (uint32_t chn) { + if (!_monitor) { + return; + } + char buf[64]; snprintf (buf, sizeof (buf), "monitor-cut-%u", chn); @@ -424,6 +464,10 @@ MonitorSection::cut_channel (uint32_t chn) void MonitorSection::dim_channel (uint32_t chn) { + if (!_monitor) { + return; + } + char buf[64]; snprintf (buf, sizeof (buf), "monitor-dim-%u", chn); @@ -440,6 +484,10 @@ MonitorSection::dim_channel (uint32_t chn) void MonitorSection::solo_channel (uint32_t chn) { + if (!_monitor) { + return; + } + char buf[64]; snprintf (buf, sizeof (buf), "monitor-solo-%u", chn); @@ -456,6 +504,10 @@ MonitorSection::solo_channel (uint32_t chn) void MonitorSection::invert_channel (uint32_t chn) { + if (!_monitor) { + return; + } + char buf[64]; snprintf (buf, sizeof (buf), "monitor-invert-%u", chn); @@ -625,19 +677,25 @@ MonitorSection::setup_knob_images () void MonitorSection::gain_value_changed () { - _route->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this); + if (_route) { + _route->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this); + } } void MonitorSection::dim_level_changed () { - _monitor->set_dim_level (dim_adjustment.get_value()); + if (_monitor) { + _monitor->set_dim_level (dim_adjustment.get_value()); + } } void MonitorSection::solo_boost_changed () { - _monitor->set_solo_boost_level (solo_boost_adjustment.get_value()); + if (_monitor) { + _monitor->set_solo_boost_level (solo_boost_adjustment.get_value()); + } } bool @@ -663,6 +721,10 @@ MonitorSection::linear_gain_printer (SpinButton* button) void MonitorSection::map_state () { + if (!_route || !_monitor) { + return; + } + gain_control->get_adjustment()->set_value (gain_to_slider_position (_route->gain_control()->get_value())); dim_control->get_adjustment()->set_value (_monitor->dim_level()); solo_boost_control->get_adjustment()->set_value (_monitor->solo_boost_level()); diff --git a/gtk2_ardour/monitor_section.h b/gtk2_ardour/monitor_section.h index 0a8909def8..405b8eba87 100644 --- a/gtk2_ardour/monitor_section.h +++ b/gtk2_ardour/monitor_section.h @@ -38,10 +38,14 @@ class MonitorSection : public RouteUI MonitorSection (ARDOUR::Session*); ~MonitorSection (); + void set_session (ARDOUR::Session*); + Gtk::Widget& pack_widget () const; void fast_update (); static void setup_knob_images (); + Gtkmm2ext::TearOff* tearoff() const { return _tearoff; } + private: Gtk::VBox vpacker; Gtk::HBox hpacker; diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 1ddee9a585..d84cf589fb 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -52,6 +52,10 @@ namespace Gtk { class Menu; } +namespace Gtkmm2ext { + class TearOff; +} + class Editor; class TimeAxisViewItem; class TimeAxisView; @@ -359,6 +363,9 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible { virtual TrackViewList axis_views_from_routes (boost::shared_ptr) const = 0; virtual TrackViewList const & get_track_views () = 0; + virtual Gtkmm2ext::TearOff* mouse_mode_tearoff () const = 0; + virtual Gtkmm2ext::TearOff* tools_tearoff () const = 0; + /// Singleton instance, set up by Editor::Editor() static PublicEditor* _instance; diff --git a/libs/gtkmm2ext/gtkmm2ext/tearoff.h b/libs/gtkmm2ext/gtkmm2ext/tearoff.h index 737a6ddd03..db01684e2f 100644 --- a/libs/gtkmm2ext/gtkmm2ext/tearoff.h +++ b/libs/gtkmm2ext/gtkmm2ext/tearoff.h @@ -25,6 +25,8 @@ #include #include +class XMLNode; + namespace Gtkmm2ext { class TearOff : public Gtk::HBox @@ -44,6 +46,11 @@ class TearOff : public Gtk::HBox Gtk::Window& tearoff_window() { return own_window; } bool torn_off() const; + void tear_it_off (); + void put_it_back (); + + void set_tornoff_state (const XMLNode&); + void add_tornoff_state (XMLNode&) const; private: Gtk::Widget& contents; @@ -58,6 +65,10 @@ class TearOff : public Gtk::HBox bool dragging; bool _visible; bool _can_be_torn_off; + int own_window_width; + int own_window_height; + int own_window_xpos; + int own_window_ypos; gint tearoff_click (GdkEventButton*); gint close_click (GdkEventButton*); @@ -66,6 +77,9 @@ class TearOff : public Gtk::HBox gint window_button_press (GdkEventButton*); gint window_button_release (GdkEventButton*); gint window_delete_event (GdkEventAny*); + + void own_window_realized (); + bool own_window_configured (GdkEventConfigure*); }; } /* namespace */ diff --git a/libs/gtkmm2ext/tearoff.cc b/libs/gtkmm2ext/tearoff.cc index c33663e8f7..28fb5ba4ef 100644 --- a/libs/gtkmm2ext/tearoff.cc +++ b/libs/gtkmm2ext/tearoff.cc @@ -20,8 +20,13 @@ #include #include -#include -#include + +#include "pbd/xml++.h" + +#include "gtkmm2ext/tearoff.h" +#include "gtkmm2ext/utils.h" + +#include "i18n.h" using namespace Gtkmm2ext; using namespace Gtk; @@ -38,6 +43,10 @@ TearOff::TearOff (Widget& c, bool allow_resize) dragging = false; _visible = true; _can_be_torn_off = true; + own_window_width = 0; + own_window_height = 0; + own_window_xpos = 0; + own_window_ypos = 0; tearoff_event_box.add (tearoff_arrow); tearoff_event_box.set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK); @@ -50,7 +59,9 @@ TearOff::TearOff (Widget& c, bool allow_resize) own_window.add_events (KEY_PRESS_MASK|KEY_RELEASE_MASK|BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK|POINTER_MOTION_MASK|POINTER_MOTION_HINT_MASK); own_window.set_resizable (allow_resize); own_window.set_type_hint (WINDOW_TYPE_HINT_TOOLBAR); - + own_window.signal_realize().connect (sigc::mem_fun (*this, &TearOff::own_window_realized)); + own_window.signal_configure_event().connect (sigc::mem_fun (*this, &TearOff::own_window_configured), false); + VBox* box1; box1 = manage (new VBox); box1->pack_start (close_event_box, false, false, 2); @@ -73,7 +84,6 @@ TearOff::TearOff (Widget& c, bool allow_resize) pack_start (contents); pack_start (*box2, false, false, 2); - } TearOff::~TearOff () @@ -119,32 +129,52 @@ TearOff::set_visible (bool yn) gint TearOff::tearoff_click (GdkEventButton* /*ev*/) { - if (_can_be_torn_off) { - remove (contents); - window_box.pack_start (contents); - own_window.set_name (get_name()); - close_event_box.set_name (get_name()); - own_window.show_all (); - own_window.present (); - std::cerr << "own window should be visible\n"; - hide (); - Detach (); - } - + tear_it_off (); return true; } +void +TearOff::tear_it_off () +{ + if (!_can_be_torn_off) { + return; + } + + if (torn_off()) { + return; + } + + remove (contents); + window_box.pack_start (contents); + own_window.set_name (get_name()); + close_event_box.set_name (get_name()); + own_window.show_all (); + own_window.present (); + hide (); + Detach (); +} + gint TearOff::close_click (GdkEventButton* /*ev*/) { + put_it_back (); + return true; +} + +void +TearOff::put_it_back () +{ + if (!torn_off()) { + return; + } + window_box.remove (contents); pack_start (contents); reorder_child (contents, 0); own_window.hide (); show_all (); Attach (); - return true; -} +} gint TearOff::window_button_press (GdkEventButton* ev) @@ -217,3 +247,79 @@ TearOff::torn_off() const { return own_window.is_visible(); } + +void +TearOff::add_tornoff_state (XMLNode& node) const +{ + node.add_property ("tornoff", (own_window.is_visible() ? "yes" : "no")); + + if (own_window_width > 0) { + char buf[32]; + + snprintf (buf, sizeof (buf), "%d", own_window_width); + node.add_property ("width", buf); + snprintf (buf, sizeof (buf), "%d", own_window_height); + node.add_property ("height", buf); + snprintf (buf, sizeof (buf), "%d", own_window_xpos); + node.add_property ("xpos", buf); + snprintf (buf, sizeof (buf), "%d", own_window_ypos); + node.add_property ("ypos", buf); + } +} + +void +TearOff::set_tornoff_state (const XMLNode& node) +{ + Glib::RefPtr win; + const XMLProperty* prop; + + if ((prop = node.property (X_("tornoff"))) == 0) { + return; + } + + if (prop->value() == "yes") { + tear_it_off (); + } else { + put_it_back (); + } + + if ((prop = node.property (X_("width"))) != 0) { + sscanf (prop->value().c_str(), "%d", &own_window_width); + } + if ((prop = node.property (X_("height"))) != 0) { + sscanf (prop->value().c_str(), "%d", &own_window_height); + } + if ((prop = node.property (X_("xpos"))) != 0) { + sscanf (prop->value().c_str(), "%d", &own_window_xpos); + } + if ((prop = node.property (X_("ypos"))) != 0) { + sscanf (prop->value().c_str(), "%d", &own_window_ypos); + } + + own_window.set_default_size (own_window_width, own_window_height); + own_window.move (own_window_xpos, own_window_ypos); +} + +void +TearOff::own_window_realized () +{ + if (own_window_width > 0) { + own_window.set_default_size (own_window_width, own_window_height); + own_window.move (own_window_xpos, own_window_ypos); + } +} + +bool +TearOff::own_window_configured (GdkEventConfigure*) +{ + Glib::RefPtr win; + + win = own_window.get_window (); + + if (win) { + win->get_size (own_window_width, own_window_height); + win->get_position (own_window_xpos, own_window_ypos); + } + + return false; +} diff --git a/libs/pbd/crossthread.cc b/libs/pbd/crossthread.cc index 2bcb444b36..7ccf741380 100644 --- a/libs/pbd/crossthread.cc +++ b/libs/pbd/crossthread.cc @@ -104,3 +104,15 @@ CrossThreadChannel::drain (int fd) char buf[64]; while (::read (fd, buf, sizeof (buf)) > 0); } + +int +CrossThreadChannel::deliver (char msg) +{ + return ::write (fds[1], &msg, 1); +} + +int +CrossThreadChannel::receive (char& msg) +{ + return ::read (fds[0], &msg, 1); +} diff --git a/libs/pbd/pbd/crossthread.h b/libs/pbd/pbd/crossthread.h index 7a323e198f..f9845eedf0 100644 --- a/libs/pbd/pbd/crossthread.h +++ b/libs/pbd/pbd/crossthread.h @@ -30,6 +30,9 @@ class CrossThreadChannel { void wakeup(); int selectable() const { return fds[0]; } + int deliver (char msg); + int receive (char& msg); + void drain (); static void drain (int fd); -- cgit v1.2.3