#include "gtkmm2ext/choice.h"
#include "gtkmm2ext/cell_renderer_pixbuf_toggle.h"
+#include "ardour/analysis_graph.h"
#include "ardour/audio_track.h"
#include "ardour/audioengine.h"
#include "ardour/audioregion.h"
#include "editor_routes.h"
#include "editor_snapshots.h"
#include "editor_summary.h"
+#include "export_report.h"
#include "global_port_matrix.h"
#include "gui_object.h"
#include "gui_thread.h"
#include "keyboard.h"
+#include "keyeditor.h"
#include "luainstance.h"
#include "marker.h"
#include "midi_region_view.h"
#include "rgb_macros.h"
#include "rhythm_ferret.h"
#include "selection.h"
+#include "simple_progress_dialog.h"
#include "sfdb_ui.h"
#include "tempo_lines.h"
#include "time_axis_view.h"
N_("Right"),
N_("Center"),
N_("Playhead"),
- N_("Mouse"),
- N_("Edit point"),
+ N_("Mouse"),
+ N_("Edit point"),
0
};
, tempo_lines (0)
, global_rect_group (0)
, time_line_group (0)
- , tempo_or_meter_marker_menu (0)
+ , tempo_marker_menu (0)
+ , meter_marker_menu (0)
, marker_menu (0)
, range_marker_menu (0)
, transport_marker_menu (0)
, show_gain_after_trim (false)
, selection_op_cmd_depth (0)
, selection_op_history_it (0)
+ , no_save_instant (false)
, current_timefx (0)
, current_mixer_strip (0)
, show_editor_mixer_when_tracks_arrive (false)
TimeAxisView::setup_sizes ();
ArdourMarker::setup_sizes (timebar_height);
+ TempoCurve::setup_sizes (timebar_height);
bbt_label.set_name ("EditorRulerLabel");
bbt_label.set_size_request (-1, (int)timebar_height);
void
Editor::instant_save ()
{
- if (!constructed || !ARDOUR_UI::instance()->session_loaded) {
+ if (!constructed || !ARDOUR_UI::instance()->session_loaded || no_save_instant) {
return;
}
}
void
-Editor::control_select (uint32_t rid, Selection::Operation op)
+Editor::control_select (uint16_t rid, Selection::Operation op)
{
/* handles the (static) signal from the ControlProtocol class that
* requests setting the selected track to a given RID
return;
}
- boost::shared_ptr<Route> r = _session->route_by_remote_id (rid);
+ boost::shared_ptr<Route> r = _session->get_remote_nth_route (rid);
if (!r) {
return;
/* leaving window, so reset focus, thus ending any and
all text entry operations.
*/
- reset_focus();
+ reset_focus (&contents());
break;
}
break;
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Editor::add_routes, this, _1), gui_context());
_session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_title, this), gui_context());
_session->tempo_map().PropertyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::tempo_map_changed, this, _1), gui_context());
+ _session->tempo_map().MetricPositionChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::marker_position_changed, this), gui_context());
_session->Located.connect (_session_connections, invalidator (*this), boost::bind (&Editor::located, this), gui_context());
_session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::parameter_changed, this, _1), gui_context());
_session->StateSaved.connect (_session_connections, invalidator (*this), boost::bind (&Editor::session_state_saved, this, _1), gui_context());
{
using namespace Menu_Helpers;
- MenuList& edit_items = track_context_menu.items();
+ MenuList& edit_items = track_context_menu.items();
edit_items.clear();
add_dstream_context_items (edit_items);
{
using namespace Menu_Helpers;
- MenuList& edit_items = track_context_menu.items();
+ MenuList& edit_items = track_context_menu.items();
edit_items.clear();
add_bus_context_items (edit_items);
}
void
-Editor::analyze_region_selection ()
+Editor::loudness_analyze_region_selection ()
+{
+ if (!_session) {
+ return;
+ }
+ Selection& s (PublicEditor::instance ().get_selection ());
+ RegionSelection ars = s.regions;
+ ARDOUR::AnalysisGraph ag (_session);
+ framecnt_t total_work = 0;
+
+ for (RegionSelection::iterator j = ars.begin (); j != ars.end (); ++j) {
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*j);
+ if (!arv) {
+ continue;
+ }
+ if (!boost::dynamic_pointer_cast<AudioRegion> (arv->region ())) {
+ continue;
+ }
+ assert (dynamic_cast<RouteTimeAxisView *> (&arv->get_time_axis_view ()));
+ total_work += arv->region ()->length ();
+ }
+
+ SimpleProgressDialog spd (_("Region Loudness Analysis"), sigc::mem_fun (ag, &AnalysisGraph::cancel));
+ ScopedConnection c;
+ ag.set_total_frames (total_work);
+ ag.Progress.connect_same_thread (c, boost::bind (&SimpleProgressDialog::update_progress, &spd, _1, _2));
+ spd.show();
+
+ for (RegionSelection::iterator j = ars.begin (); j != ars.end (); ++j) {
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*j);
+ if (!arv) {
+ continue;
+ }
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (arv->region ());
+ if (!ar) {
+ continue;
+ }
+ ag.analyze_region (ar);
+ }
+ spd.hide();
+ if (!ag.canceled ()) {
+ ExportReport er (_("Audio Report/Analysis"), ag.results ());
+ er.run();
+ }
+}
+
+void
+Editor::loudness_analyze_range_selection ()
+{
+ if (!_session) {
+ return;
+ }
+ Selection& s (PublicEditor::instance ().get_selection ());
+ TimeSelection ts = s.time;
+ ARDOUR::AnalysisGraph ag (_session);
+ framecnt_t total_work = 0;
+
+ for (TrackSelection::iterator i = s.tracks.begin (); i != s.tracks.end (); ++i) {
+ boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist> ((*i)->playlist ());
+ if (!pl) {
+ continue;
+ }
+ RouteUI *rui = dynamic_cast<RouteUI *> (*i);
+ if (!pl || !rui) {
+ continue;
+ }
+ for (std::list<AudioRange>::iterator j = ts.begin (); j != ts.end (); ++j) {
+ total_work += j->length ();
+ }
+ }
+
+ SimpleProgressDialog spd (_("Range Loudness Analysis"), sigc::mem_fun (ag, &AnalysisGraph::cancel));
+ ScopedConnection c;
+ ag.set_total_frames (total_work);
+ ag.Progress.connect_same_thread (c, boost::bind (&SimpleProgressDialog::update_progress, &spd, _1, _2));
+ spd.show();
+
+ for (TrackSelection::iterator i = s.tracks.begin (); i != s.tracks.end (); ++i) {
+ boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist> ((*i)->playlist ());
+ if (!pl) {
+ continue;
+ }
+ RouteUI *rui = dynamic_cast<RouteUI *> (*i);
+ if (!pl || !rui) {
+ continue;
+ }
+ ag.analyze_range (rui->route (), pl, ts);
+ }
+ spd.hide();
+ if (!ag.canceled ()) {
+ ExportReport er (_("Audio Report/Analysis"), ag.results ());
+ er.run();
+ }
+}
+
+void
+Editor::spectral_analyze_region_selection ()
{
if (analysis_window == 0) {
analysis_window = new AnalysisWindow();
}
void
-Editor::analyze_range_selection()
+Editor::spectral_analyze_range_selection()
{
if (analysis_window == 0) {
analysis_window = new AnalysisWindow();
edit_items.push_back (MenuElem (_("Zoom to Range"), sigc::bind (sigc::mem_fun(*this, &Editor::temporal_zoom_selection), false)));
edit_items.push_back (SeparatorElem());
- edit_items.push_back (MenuElem (_("Spectral Analysis"), sigc::mem_fun(*this, &Editor::analyze_range_selection)));
+ edit_items.push_back (MenuElem (_("Loudness Analysis"), sigc::mem_fun(*this, &Editor::loudness_analyze_range_selection)));
+ edit_items.push_back (MenuElem (_("Spectral Analysis"), sigc::mem_fun(*this, &Editor::spectral_analyze_range_selection)));
edit_items.push_back (SeparatorElem());
return _snap_type;
}
+bool
+Editor::snap_musical() const
+{
+ switch (_snap_type) {
+ case SnapToBeatDiv128:
+ case SnapToBeatDiv64:
+ case SnapToBeatDiv32:
+ case SnapToBeatDiv28:
+ case SnapToBeatDiv24:
+ case SnapToBeatDiv20:
+ case SnapToBeatDiv16:
+ case SnapToBeatDiv14:
+ case SnapToBeatDiv12:
+ case SnapToBeatDiv10:
+ case SnapToBeatDiv8:
+ case SnapToBeatDiv7:
+ case SnapToBeatDiv6:
+ case SnapToBeatDiv5:
+ case SnapToBeatDiv4:
+ case SnapToBeatDiv3:
+ case SnapToBeatDiv2:
+ case SnapToBeat:
+ case SnapToBar:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
SnapMode
Editor::snap_mode() const
{
case SnapToBeatDiv4:
case SnapToBeatDiv3:
case SnapToBeatDiv2: {
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
-
- compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
+ std::vector<TempoMap::BBTPoint> grid;
+ compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
+ compute_bbt_ruler_scale (grid, leftmost_frame, leftmost_frame + current_page_samples());
+ update_tempo_based_rulers (grid);
break;
}
int
Editor::set_state (const XMLNode& node, int version)
{
- const XMLProperty* prop;
+ XMLProperty const * prop;
set_id (node);
+ PBD::Unwinder<bool> nsi (no_save_instant, true);
Tabbable::set_state (node, version);
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));
}
if ((prop = node.property ("snap-mode"))) {
snap_mode_selection_done((SnapMode) string_2_enum (prop->value(), _snap_mode));
+ /* set text of Dropdown. in case _snap_mode == SnapOff (default)
+ * snap_mode_selection_done() will only mark an already active item as active
+ * which does not trigger set_text().
+ */
+ set_snap_mode ((SnapMode) string_2_enum (prop->value(), _snap_mode));
}
if ((prop = node.property ("internal-snap-to"))) {
node->add_child_nocopy (Tabbable::get_state());
- snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (static_cast<Paned*>(&edit_pane)->gobj()));
+ snprintf(buf,sizeof(buf), "%f", paned_position_as_fraction (edit_pane, false));
node->add_property("edit-horizontal-pane-pos", string(buf));
node->add_property("notebook-shrunk", _notebook_shrunk ? "1" : "0");
- snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (static_cast<Paned*>(&editor_summary_pane)->gobj()));
+ snprintf(buf,sizeof(buf), "%f", paned_position_as_fraction (editor_summary_pane, true));
node->add_property("edit-vertical-pane-pos", string(buf));
maybe_add_mixer_strip_width (*node);
Editor::edit_controls_button_release (GdkEventButton* ev)
{
if (Keyboard::is_context_menu_event (ev)) {
- ARDOUR_UI::instance()->add_route (current_toplevel());
+ ARDOUR_UI::instance()->add_route ();
} else if (ev->button == 1) {
selection->clear_tracks ();
}
{
/* recover or initialize pane positions. do this here rather than earlier because
we don't want the positions to change the child allocations, which they seem to do.
+
+ See comments in mixer_ui.cc about how this works.
*/
- int pos;
+ float pos;
XMLProperty* prop;
- char buf[32];
- XMLNode* node = ARDOUR_UI::instance()->editor_settings();
+ XMLNode* geometry = ARDOUR_UI::instance()->editor_settings();
enum Pane {
Horizontal = 0x1,
static Pane done;
- XMLNode* geometry = find_named_node (*node, "geometry");
-
if (which == static_cast<Paned*> (&edit_pane)) {
if (done & Horizontal) {
if (!geometry || (prop = geometry->property ("edit-horizontal-pane-pos")) == 0) {
/* initial allocation is 90% to canvas, 10% to notebook */
pos = (int) floor (alloc.get_width() * 0.90f);
- snprintf (buf, sizeof(buf), "%d", pos);
} else {
- pos = atoi (prop->value());
+ pos = atof (prop->value());
}
- if (GTK_WIDGET(edit_pane.gobj())->allocation.width > pos) {
- edit_pane.set_position (pos);
+ if (pos > 1.0f) {
+ /* older versions of Ardour stored absolute position */
+ if (alloc.get_width() > pos) {
+ edit_pane.set_position (pos);
+ done = (Pane) (done | Horizontal);
+ }
+ } else {
+ if (alloc.get_width() > 1.0/pos) {
+ paned_set_position_as_fraction (edit_pane, pos, false);
+ done = (Pane) (done | Horizontal);
+ }
}
- done = (Pane) (done | Horizontal);
-
} else if (which == static_cast<Paned*> (&editor_summary_pane)) {
if (done & Vertical) {
if (!geometry || (prop = geometry->property ("edit-vertical-pane-pos")) == 0) {
/* initial allocation is 90% to canvas, 10% to summary */
pos = (int) floor (alloc.get_height() * 0.90f);
- snprintf (buf, sizeof(buf), "%d", pos);
} else {
- pos = atoi (prop->value());
+ pos = atof (prop->value());
}
- if (GTK_WIDGET(editor_summary_pane.gobj())->allocation.height > pos) {
- editor_summary_pane.set_position (pos);
+ if (pos > 1.0f) {
+ /* older versions of Ardour stored absolute position */
+ if (alloc.get_height() > pos) {
+ editor_summary_pane.set_position (pos);
+ done = (Pane) (done | Vertical);
+ }
+ } else {
+ if (alloc.get_height() > 1.0/pos) {
+ paned_set_position_as_fraction (editor_summary_pane, pos, true);
+ done = (Pane) (done | Vertical);
+ }
}
-
- done = (Pane) (done | Vertical);
}
}
tempo_lines->show();
}
- ARDOUR::TempoMap::BBTPointList::const_iterator begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator end;
-
- compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(), begin, end);
- draw_measures (begin, end);
+ std::vector<TempoMap::BBTPoint> grid;
+ compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
+ draw_measures (grid);
}
instant_save ();
return Evoral::Beats(1.0);
case SnapToBar:
if (_session) {
- return Evoral::Beats(_session->tempo_map().meter_at (position).divisions_per_bar());
+ return Evoral::Beats(_session->tempo_map().meter_at_frame (position).divisions_per_bar());
}
break;
default:
compute_fixed_ruler_scale ();
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
- ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
-
- compute_current_bbt_points (vc.time_origin, pending_visual_change.time_origin + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- compute_bbt_ruler_scale (vc.time_origin, pending_visual_change.time_origin + current_page_samples(),
- current_bbt_points_begin, current_bbt_points_end);
- update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
+ std::vector<TempoMap::BBTPoint> grid;
+ compute_current_bbt_points (grid, vc.time_origin, pending_visual_change.time_origin + current_page_samples());
+ compute_bbt_ruler_scale (grid, vc.time_origin, pending_visual_change.time_origin + current_page_samples());
+ update_tempo_based_rulers (grid);
update_video_timeline();
}
*/
RegionSelection
-Editor::get_regions_from_selection_and_entered ()
+Editor::get_regions_from_selection_and_entered () const
{
RegionSelection regions = selection->regions;
SessionHandlePtr::session_going_away ();
}
-void
-Editor::manage_action_scripts ()
-{
- ARDOUR_UI::instance()->lua_script_manager();
-}
-
void
Editor::trigger_script (int i)
{
assert (act);
if (n.empty ()) {
act->set_label (string_compose (_("Unset #%1"), i + 1));
+ act->set_tooltip (_("no action bound"));
+ act->set_sensitive (false);
} else {
act->set_label (n);
+ act->set_tooltip (n);
+ act->set_sensitive (true);
}
+ KeyEditor::UpdateBindings ();
}
void