#include "ardour/lmath.h"
#include "ardour/location.h"
#include "ardour/profile.h"
+#include "ardour/route.h"
#include "ardour/route_group.h"
#include "ardour/session_playlists.h"
#include "ardour/tempo.h"
#include "ardour/utils.h"
#include "ardour/vca_manager.h"
+#include "ardour/vca.h"
#include "canvas/debug.h"
#include "canvas/text.h"
#include "region_layering_order_editor.h"
#include "rgb_macros.h"
#include "rhythm_ferret.h"
+#include "route_sorter.h"
#include "selection.h"
#include "simple_progress_dialog.h"
#include "sfdb_ui.h"
_notebook_shrunk = string_is_affirmative (prop->value ());
}
+ editor_summary_pane.set_check_divider_position (true);
editor_summary_pane.add (edit_packer);
Button* summary_arrows_left_left = manage (new Button);
editor_summary_pane.add (_summary_hbox);
}
+ edit_pane.set_check_divider_position (true);
edit_pane.add (editor_summary_pane);
if (!ARDOUR::Profile->get_trx()) {
edit_pane.add (_the_notebook);
float fract;
- if (!settings || ((prop = settings->property ("edit-horizontal-pane-pos")) == 0) || ((fract = atof (prop->value())) > 1.0)) {
- /* initial allocation is 90% to canvas, 10% to notebook */
- edit_pane.set_divider (0, 0.90);
- } else {
- edit_pane.set_divider (0, fract);
- }
+ {
+ LocaleGuard lg;
- if (!settings || ((prop = settings->property ("edit-vertical-pane-pos")) == 0) || ((fract = atof (prop->value())) > 1.0)) {
- /* initial allocation is 90% to canvas, 10% to summary */
- editor_summary_pane.set_divider (0, 0.90);
- } else {
+ if (!settings || ((prop = settings->property ("edit-horizontal-pane-pos")) == 0) || ((fract = atof (prop->value())) > 1.0)) {
+ /* initial allocation is 90% to canvas, 10% to notebook */
+ edit_pane.set_divider (0, 0.90);
+ } else {
+ edit_pane.set_divider (0, fract);
+ }
+
+ if (!settings || ((prop = settings->property ("edit-vertical-pane-pos")) == 0) || ((fract = atof (prop->value())) > 1.0)) {
+ /* initial allocation is 90% to canvas, 10% to summary */
+ editor_summary_pane.set_divider (0, 0.90);
+ } else {
- editor_summary_pane.set_divider (0, fract);
+ editor_summary_pane.set_divider (0, fract);
+ }
}
top_hbox.pack_start (toolbar_frame);
ControlProtocol::VerticalZoomInSelected.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_in_selected, this), gui_context());
ControlProtocol::VerticalZoomOutSelected.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_out_selected, this), gui_context());
- ControlProtocol::AddStripableToSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Add), gui_context());
- ControlProtocol::RemoveStripableFromSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Toggle), gui_context());
- ControlProtocol::SetStripableSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Set), gui_context());
- ControlProtocol::ToggleStripableSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Toggle), gui_context());
- ControlProtocol::ClearStripableSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_unselect, this), gui_context());
-
BasicUI::AccessAction.connect (*this, invalidator (*this), boost::bind (&Editor::access_action, this, _1, _2), gui_context());
/* handle escape */
selection->clear_tracks ();
}
-void
-Editor::control_select (PresentationInfo::global_order_t global_order, Selection::Operation op)
-{
- /* handles the (static) signal from the ControlProtocol class that
- * requests setting the selected track to a given RID
- */
-
- if (!_session) {
- return;
- }
-
- PresentationInfo::Flag select_flags;
-
- if (global_order & ~0xffffffff) {
- /* some flags are set, so the PresentationInfo constructor
- * will use them
- */
- select_flags = PresentationInfo::Flag (0);
- } else {
- /* no type flags set in the global order ID, so assume caller
- * wants to select a Route
- */
- select_flags = PresentationInfo::Route;
- }
-
- PresentationInfo pi (global_order, select_flags);
- boost::shared_ptr<Stripable> s = _session->get_remote_nth_stripable (pi.group_order(), pi.flags());
-
- /* selected object may not be a Route */
-
- boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
-
- if (!r) {
- return;
- }
-
- TimeAxisView* tav = axis_view_from_route (r);
-
- if (tav) {
- switch (op) {
- case Selection::Add:
- selection->add (tav);
- break;
- case Selection::Toggle:
- selection->toggle (tav);
- break;
- case Selection::Extend:
- break;
- case Selection::Set:
- selection->set (tav);
- break;
- }
- } else {
- selection->clear_tracks ();
- }
-}
-
void
Editor::control_step_tracks_up ()
{
break;
}
+ /* catch up on selection of stripables (other selection state is lost
+ * when a session is closed
+ */
+
+ StripableList sl;
+ TrackViewList tl;
+ _session->get_stripables (sl);
+ for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) {
+ if ((*s)->presentation_info().selected()) {
+ RouteTimeAxisView* rtav = get_route_view_by_route_id ((*s)->id());
+ if (rtav) {
+ tl.push_back (rtav);
+ }
+ }
+ }
+ if (!tl.empty()) {
+ selection->set (tl);
+ }
+
/* register for undo history */
_session->register_with_memento_command_factory(id(), this);
_session->register_with_memento_command_factory(_selection_memento->id(), _selection_memento);
if ((prop = node.property ("zoom-focus"))) {
zoom_focus_selection_done ((ZoomFocus) string_2_enum (prop->value(), zoom_focus));
+ } else {
+ zoom_focus_selection_done (zoom_focus);
}
if ((prop = node.property ("zoom"))) {
if ((prop = node.property ("snap-to"))) {
snap_type_selection_done ((SnapType) string_2_enum (prop->value(), _snap_type));
set_snap_to ((SnapType) string_2_enum (prop->value(), _snap_type));
+ } else {
+ set_snap_to (_snap_type);
}
if ((prop = node.property ("snap-mode"))) {
* which does not trigger set_text().
*/
set_snap_mode ((SnapMode) string_2_enum (prop->value(), _snap_mode));
+ } else {
+ set_snap_mode (_snap_mode);
}
if ((prop = node.property ("internal-snap-to"))) {
if ((prop = node.property ("edit-point"))) {
set_edit_point_preference ((EditPoint) string_2_enum (prop->value(), _edit_point), true);
+ } else {
+ set_edit_point_preference (_edit_point);
}
if ((prop = node.property ("show-measures"))) {
return 0;
}
+/** returns the current musical grid divisiions using the supplied modifier mask from a GtkEvent.
+ if the grid is non-musical, returns 0.
+ if the grid is snapped to bars, returns -1.
+ @param event_state the current keyboard modifier mask.
+*/
+unsigned
+Editor::get_grid_music_divisions (uint32_t event_state)
+{
+ if (snap_mode() == Editing::SnapOff && !ArdourKeyboard::indicates_snap (event_state)) {
+ return 0;
+ }
+
+ if (snap_mode() != Editing::SnapOff && ArdourKeyboard::indicates_snap (event_state)) {
+ return 0;
+ }
+
+ switch (_snap_type) {
+ case SnapToBeatDiv128: return 128;
+ case SnapToBeatDiv64: return 64;
+ case SnapToBeatDiv32: return 32;
+ case SnapToBeatDiv28: return 28;
+ case SnapToBeatDiv24: return 24;
+ case SnapToBeatDiv20: return 20;
+ case SnapToBeatDiv16: return 16;
+ case SnapToBeatDiv14: return 14;
+ case SnapToBeatDiv12: return 12;
+ case SnapToBeatDiv10: return 10;
+ case SnapToBeatDiv8: return 8;
+ case SnapToBeatDiv7: return 7;
+ case SnapToBeatDiv6: return 6;
+ case SnapToBeatDiv5: return 5;
+ case SnapToBeatDiv4: return 4;
+ case SnapToBeatDiv3: return 3;
+ case SnapToBeatDiv2: return 2;
+ case SnapToBeat: return 1;
+ case SnapToBar : return -1;
+ default: return 0;
+ }
+ return 0;
+}
+
Evoral::Beats
Editor::get_grid_type_as_beats (bool& success, framepos_t position)
{
begin_reversible_command (_("new playlists"));
vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
_session->playlists->get (playlists);
- mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_new_playlist), playlists), v, ARDOUR::Properties::select.property_id);
+ mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_new_playlist), playlists), v, ARDOUR::Properties::group_select.property_id);
commit_reversible_command ();
}
begin_reversible_command (_("copy playlists"));
vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
_session->playlists->get (playlists);
- mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_copy_playlist), playlists), v, ARDOUR::Properties::select.property_id);
+ mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_copy_playlist), playlists), v, ARDOUR::Properties::group_select.property_id);
commit_reversible_command ();
}
begin_reversible_command (_("clear playlists"));
vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
_session->playlists->get (playlists);
- mapover_tracks (sigc::mem_fun (*this, &Editor::mapped_clear_playlist), v, ARDOUR::Properties::select.property_id);
+ mapover_tracks (sigc::mem_fun (*this, &Editor::mapped_clear_playlist), v, ARDOUR::Properties::group_select.property_id);
commit_reversible_command ();
}
}
void
-Editor::add_vcas (VCAList& vcas)
+Editor::add_vcas (VCAList& vlist)
{
- VCATimeAxisView* vtv;
- list<VCATimeAxisView*> new_views;
+ StripableList sl;
- for (VCAList::iterator v = vcas.begin(); v != vcas.end(); ++v) {
- vtv = new VCATimeAxisView (*this, _session, *_track_canvas);
- vtv->set_vca (*v);
- new_views.push_back (vtv);
+ for (VCAList::iterator v = vlist.begin(); v != vlist.end(); ++v) {
+ sl.push_back (boost::dynamic_pointer_cast<Stripable> (*v));
}
- if (new_views.size() > 0) {
- _routes->vcas_added (new_views);
- }
+ add_stripables (sl);
}
void
-Editor::add_routes (RouteList& routes)
+Editor::add_routes (RouteList& rlist)
{
- ENSURE_GUI_THREAD (*this, &Editor::handle_new_route, routes)
+ StripableList sl;
+
+ for (RouteList::iterator r = rlist.begin(); r != rlist.end(); ++r) {
+ sl.push_back (*r);
+ }
- RouteTimeAxisView *rtv;
- list<RouteTimeAxisView*> new_views;
+ add_stripables (sl);
+}
+
+void
+Editor::add_stripables (StripableList& sl)
+{
+ list<TimeAxisView*> new_views;
+ boost::shared_ptr<VCA> v;
+ boost::shared_ptr<Route> r;
TrackViewList new_selection;
bool from_scratch = (track_views.size() == 0);
- for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
- boost::shared_ptr<Route> route = (*x);
+ sl.sort (StripablePresentationInfoSorter());
- if (route->is_auditioner() || route->is_monitor()) {
- continue;
- }
+ for (StripableList::iterator s = sl.begin(); s != sl.end(); ++s) {
- DataType dt = route->input()->default_type();
+ if ((v = boost::dynamic_pointer_cast<VCA> (*s)) != 0) {
- if (dt == ARDOUR::DataType::AUDIO) {
- rtv = new AudioTimeAxisView (*this, _session, *_track_canvas);
- rtv->set_route (route);
- } else if (dt == ARDOUR::DataType::MIDI) {
- rtv = new MidiTimeAxisView (*this, _session, *_track_canvas);
- rtv->set_route (route);
- } else {
- throw unknown_type();
- }
+ VCATimeAxisView* vtv = new VCATimeAxisView (*this, _session, *_track_canvas);
+ vtv->set_vca (v);
+ new_views.push_back (vtv);
- new_views.push_back (rtv);
- track_views.push_back (rtv);
- new_selection.push_back (rtv);
+ } else if ((r = boost::dynamic_pointer_cast<Route> (*s)) != 0) {
- rtv->effective_gain_display ();
+ if (r->is_auditioner() || r->is_monitor()) {
+ continue;
+ }
- rtv->view()->RegionViewAdded.connect (sigc::mem_fun (*this, &Editor::region_view_added));
- rtv->view()->RegionViewRemoved.connect (sigc::mem_fun (*this, &Editor::region_view_removed));
+ RouteTimeAxisView* rtv;
+ DataType dt = r->input()->default_type();
+
+ if (dt == ARDOUR::DataType::AUDIO) {
+ rtv = new AudioTimeAxisView (*this, _session, *_track_canvas);
+ rtv->set_route (r);
+ } else if (dt == ARDOUR::DataType::MIDI) {
+ rtv = new MidiTimeAxisView (*this, _session, *_track_canvas);
+ rtv->set_route (r);
+ } else {
+ throw unknown_type();
+ }
+
+ new_views.push_back (rtv);
+ track_views.push_back (rtv);
+ new_selection.push_back (rtv);
+
+ rtv->effective_gain_display ();
+
+ rtv->view()->RegionViewAdded.connect (sigc::mem_fun (*this, &Editor::region_view_added));
+ rtv->view()->RegionViewRemoved.connect (sigc::mem_fun (*this, &Editor::region_view_removed));
+ }
}
if (new_views.size() > 0) {
- _routes->routes_added (new_views);
- _summary->routes_added (new_views);
+ _routes->time_axis_views_added (new_views);
+ //_summary->routes_added (new_selection); /* XXX requires RouteTimeAxisViewList */
}
- if (!from_scratch) {
+ /* note: !new_selection.empty() means that we got some routes rather
+ * than just VCAs
+ */
+
+ if (!from_scratch && !new_selection.empty()) {
selection->tracks.clear();
selection->add (new_selection);
begin_selection_op_history();
}
- if (show_editor_mixer_when_tracks_arrive) {
+ if (show_editor_mixer_when_tracks_arrive && !new_selection.empty()) {
show_editor_mixer (true);
}