diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index c1f03263f2..6b1ff8087d 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1431,9 +1431,7 @@ Editor::set_session (Session *t) _session->config.map_parameters (pc); //tempo_map_changed (PropertyChange (0)); - TempoMap::Metrics metrics; - TempoMap::use()->get_metrics (metrics); - draw_metric_marks (metrics); + reset_metric_marks (); for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { (static_cast(*i))->set_samples_per_pixel (samples_per_pixel); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index d49d2d07e8..d1cb61517a 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1729,7 +1729,14 @@ private: Temporal::TempoMap::WritableSharedPtr begin_tempo_map_edit (); void abort_tempo_map_edit (); - void mid_tempo_change (); + + enum MidTempoChanges { + TempoChanged = 0x1, + MeterChanged = 0x2, + BBTChanged = 0x4 + }; + + void mid_tempo_change (MidTempoChanges); private: friend class DragManager; @@ -1849,22 +1856,26 @@ private: Marks bbt_marks; void remove_metric_marks (); - void draw_metric_marks (Temporal::TempoMap::Metrics const & metrics); - void draw_tempo_marks (); - void draw_meter_marks (); - void draw_bbt_marks (); + void reset_metric_marks (); + void reset_tempo_marks (); + void reset_meter_marks (); + void reset_bbt_marks (); void compute_current_bbt_points (Temporal::TempoMapPoints& grid, samplepos_t left, samplepos_t right); void reassociate_metric_markers (Temporal::TempoMap::SharedPtr const &); - void reassociate_metric_marker (Temporal::TempoMap::SharedPtr const& tmap, Temporal::TempoMap::Metrics const& metric, MetricMarker& marker); + + void reassociate_tempo_marker (Temporal::TempoMap::SharedPtr const & tmap, Temporal::TempoMap::Tempos const &, TempoMarker& marker); + void reassociate_meter_marker (Temporal::TempoMap::SharedPtr const & tmap, Temporal::TempoMap::Meters const &, MeterMarker& marker); + void reassociate_bartime_marker (Temporal::TempoMap::SharedPtr const & tmap, Temporal::TempoMap::MusicTimes const &, BBTMarker& marker); + void make_bbt_marker (Temporal::MusicTimePoint const *, Marks::iterator before); void make_meter_marker (Temporal::MeterPoint const *, Marks::iterator before); void make_tempo_marker (Temporal::TempoPoint const * ts, double& min_tempo, double& max_tempo, Temporal::TempoPoint const *& prev_ts, uint32_t tc_color, samplecnt_t sr3, Marks::iterator before); void update_tempo_curves (double min_tempo, double max_tempo, samplecnt_t sr); void tempo_map_changed (); - void tempo_map_visual_update (); + void tempo_map_model_update (); void redisplay_grid (bool immediate_redraw); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 7c31d2e721..6b472d75e2 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3123,7 +3123,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move) if (map->move_meter (_marker->meter(), pos, leftward_earlier, false)) { /* it was moved */ - _editor->mid_tempo_change (); + _editor->mid_tempo_change (Editor::MeterChanged); show_verbose_cursor_time (timepos_t (_marker->meter().beats())); _editor->set_snapped_cursor_position (timepos_t (_marker->meter().sample(_editor->session()->sample_rate()))); } @@ -3213,7 +3213,7 @@ TempoCurveDrag::motion (GdkEvent* event, bool first_move) strs << "Tempo: " << fixed << setprecision(3) << new_bpm; show_verbose_cursor_text (strs.str()); - _editor->mid_tempo_change (); + _editor->mid_tempo_change (Editor::TempoChanged); } @@ -3319,7 +3319,7 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move) show_verbose_cursor_time (_marker->tempo().time()); } - _editor->mid_tempo_change (); + _editor->mid_tempo_change (Editor::TempoChanged); } @@ -3449,7 +3449,7 @@ BBTRulerDrag::motion (GdkEvent* event, bool first_move) if (ArdourKeyboard::indicates_constraint (event->button.state)) { /* adjust previous tempo to match pointer sample */ map->stretch_tempo (_tempo, timepos_t (_grab_qn).samples(), pf.samples(), _grab_qn, pf.beats()); - _editor->mid_tempo_change (); + _editor->mid_tempo_change (Editor::BBTChanged); } ostringstream sstr; @@ -3607,7 +3607,7 @@ TempoTwistDrag::motion (GdkEvent* event, bool first_move) } show_verbose_cursor_text (sstr.str()); - _editor->mid_tempo_change (); + _editor->mid_tempo_change (Editor::TempoChanged); } void @@ -3713,7 +3713,7 @@ TempoEndDrag::motion (GdkEvent* event, bool first_move) timepos_t const pos = adjusted_current_time (event, false); map->stretch_tempo_end (_tempo, timepos_t (_grab_qn).samples(), pos.samples()); - _editor->mid_tempo_change (); + _editor->mid_tempo_change (Editor::TempoChanged); ostringstream sstr; const samplecnt_t sr = AudioEngine::instance()->sample_rate(); diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 67d97f1685..0b01f83b44 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -92,69 +92,66 @@ void Editor::reassociate_metric_markers (TempoMap::SharedPtr const& tmap) { TempoMap::Metrics metrics; - tmap->get_metrics (metrics); - for (auto const& m : tempo_marks) { - reassociate_metric_marker (tmap, metrics, *m); + for (auto & t : tempo_marks) { + reassociate_tempo_marker (tmap, tmap->tempos(), *dynamic_cast (t)); } - for (auto const& m : meter_marks) { - reassociate_metric_marker (tmap, metrics, *m); + for (auto & m : meter_marks) { + reassociate_meter_marker (tmap, tmap->meters(), *dynamic_cast (m)); } - for (auto const& m : bbt_marks) { - reassociate_metric_marker (tmap, metrics, *m); + for (auto & b : bbt_marks) { + reassociate_bartime_marker (tmap, tmap->bartimes(), *dynamic_cast (b)); } } void -Editor::reassociate_metric_marker (TempoMap::SharedPtr const& tmap, TempoMap::Metrics const& metrics, MetricMarker& marker) +Editor::reassociate_tempo_marker (TempoMap::SharedPtr const & tmap, TempoMap::Tempos const & tempos, TempoMarker& marker) { - TempoMarker* tm; - MeterMarker* mm; - BBTMarker* bm; - - Temporal::TempoPoint const * tp; - Temporal::MeterPoint const * mp; Temporal::MusicTimePoint const * mtp; - if ((tm = dynamic_cast (&marker)) != 0) { - for (auto const& m : metrics) { - if ((mtp = dynamic_cast(m)) != 0) { - /* do nothing .. but we had to catch - this first because MusicTimePoint - IS-A TempoPoint - */ - } else if ((tp = dynamic_cast(m)) != 0) { - if (tm->tempo().sclock() == tp->sclock()) { - tm->reset_tempo (*tp); - tm->curve().reset_point (*tp); - break; - } - } + for (auto const & tempo : tempos) { + if ((mtp = dynamic_cast(&tempo)) != 0) { + /* do nothing .. but we had to catch + this first because MusicTimePoint + IS-A TempoPoint + */ + continue; } - } else if ((mm = dynamic_cast (&marker)) != 0) { - for (auto const& m : metrics) { - if ((mtp = dynamic_cast(m)) != 0) { - /* do nothing .. but we had to catch - this first because MusicTimePoint - IS-A TempoPoint - */ - - } else if ((mp = dynamic_cast(m)) != 0) { - if (mm->meter().sclock() == mp->sclock()) { - mm->reset_meter (*mp); - break; - } - } + if (marker.point().sclock() == tempo.sclock()) { + marker.reset_tempo (tempo); + marker.curve().reset_point (tempo); + break; } + } +} - } else if ((bm = dynamic_cast (&marker)) != 0) { - for (auto const& m : metrics) { - if ((mtp = dynamic_cast(m)) != 0) { - if (bm->point().sclock() == mtp->sclock()) { - bm->reset_point (*mtp); - break; - } - } +void +Editor::reassociate_meter_marker (TempoMap::SharedPtr const & tmap, TempoMap::Meters const & meters, MeterMarker& marker) +{ + Temporal::MusicTimePoint const * mtp; + + for (auto const & meter : meters) { + if ((mtp = dynamic_cast(&meter)) != 0) { + /* do nothing .. but we had to catch + this first because MusicTimePoint + IS-A MeterPoint + */ + continue; + } + if (marker.point().sclock() == meter.sclock()) { + marker.reset_meter (meter); + break; + } + } +} + +void +Editor::reassociate_bartime_marker (TempoMap::SharedPtr const & tmap, TempoMap::MusicTimes const & bartimes, BBTMarker& marker) +{ + for (auto const & bartime : bartimes) { + if (marker.point().sclock() == bartime.sclock()) { + marker.reset_point (bartime); + break; } } } @@ -201,15 +198,15 @@ Editor::make_tempo_marker (Temporal::TempoPoint const * ts, double& min_tempo, d } void -Editor::draw_metric_marks (Temporal::TempoMap::Metrics const &) +Editor::reset_metric_marks () { - draw_tempo_marks (); - draw_meter_marks (); - draw_bbt_marks (); + reset_tempo_marks (); + reset_meter_marks (); + reset_bbt_marks (); } void -Editor::draw_tempo_marks () +Editor::reset_tempo_marks () { if (!_session) { return; @@ -217,73 +214,26 @@ Editor::draw_tempo_marks () const uint32_t tc_color = UIConfiguration::instance().color ("tempo curve"); const samplecnt_t sr (_session->sample_rate()); - TempoPoint const * prev_ts = 0; + Temporal::TempoMap::SharedPtr tmap (TempoMap::use()); TempoMap::Tempos const & tempi (tmap->tempos()); - TempoMap::Tempos::const_iterator t = tempi.begin(); - Marks::iterator mm = tempo_marks.begin(); + TempoPoint const * prev_ts = 0; double max_tempo = 0.0; double min_tempo = DBL_MAX; - while (t != tempi.end() && mm != tempo_marks.end()) { - - Temporal::TempoPoint const & metric_point (*t); - - if (dynamic_cast (&metric_point)) { - ++t; - continue; - } - - /* catch BBT position elements that are both tempo & meter points */ - - Temporal::Point const & mark_point ((*mm)->point()); - - if (mark_point.sclock() < metric_point.sclock()) { - - - /* advance through markers, deleting the unused ones */ - - delete *mm; - mm = tempo_marks.erase (mm); - - - } else if (metric_point.sclock() < mark_point.sclock()) { - - make_tempo_marker (&metric_point, min_tempo, max_tempo, prev_ts, tc_color, sr, mm); - ++t; - - } else { - /* marker represents an existing point, update text, properties etc */ - /* XXX left/right text stuff */ - // (*mm)->set_name ((*m)->name()); - (*mm)->set_position (t->time()); - - max_tempo = max (max_tempo, t->note_types_per_minute()); - max_tempo = max (max_tempo, t->end_note_types_per_minute()); - min_tempo = min (min_tempo, t->note_types_per_minute()); - min_tempo = min (min_tempo, t->end_note_types_per_minute()); - - ++t; - ++mm; - } + for (auto & t : tempo_marks) { + delete t; } - if ((t == tempi.end()) && (mm != tempo_marks.end())) { - while (mm != tempo_marks.end()) { - delete *mm; - mm = tempo_marks.erase (mm); - } - } + tempo_marks.clear (); - if ((mm == tempo_marks.end())) { + for (auto const & t : tempi) { - while (t != tempi.end()) { + /* do not draw BBT position elements that are both tempo & meter points */ - if (!dynamic_cast (&(*t))) { - make_tempo_marker (&*t, min_tempo, max_tempo, prev_ts, tc_color, sr, tempo_marks.end()); - } - - ++t; + if (!dynamic_cast (&t)) { + make_tempo_marker (&t, min_tempo, max_tempo, prev_ts, tc_color, sr, tempo_marks.end()); + prev_ts = &t; } } @@ -291,7 +241,7 @@ Editor::draw_tempo_marks () } void -Editor::draw_meter_marks () +Editor::reset_meter_marks () { if (!_session) { return; @@ -299,64 +249,25 @@ Editor::draw_meter_marks () Temporal::TempoMap::SharedPtr tmap (TempoMap::use()); TempoMap::Meters const & meters (tmap->meters()); - TempoMap::Meters::const_iterator m = meters.begin(); - Marks::iterator mm = meter_marks.begin(); - while (m != meters.end() && mm != meter_marks.end()) { - - Temporal::MeterPoint const & metric_point (*m); - - if (dynamic_cast (&metric_point)) { - ++m; - continue; - } - - Temporal::Point const & mark_point ((*mm)->point()); - - if (mark_point.sclock() < metric_point.sclock()) { - - /* advance through markers, deleting the unused ones */ - - delete *mm; - mm = meter_marks.erase (mm); - - } else if (metric_point.sclock() < mark_point.sclock()) { - - make_meter_marker (&metric_point, mm); - ++m; - - } else { - /* marker represents an existing point, update text, properties etc */ - /* XXX left/right text stuff */ - // (*mm)->set_name ((*m)->name()); - (*mm)->set_position (m->time()); - ++m; - ++mm; - } + for (auto & m : meter_marks) { + delete m; } - if ((m == meters.end()) && (mm != meter_marks.end())) { - while (mm != meter_marks.end()) { - delete *mm; - mm = meter_marks.erase (mm); - } - } + meter_marks.clear (); - if ((mm == meter_marks.end()) && (m != meters.end())) { + for (auto const & m : meters) { - while (m != meters.end()) { + /* do not draw BBT position elements that are both tempo & meter points */ - if (!dynamic_cast (&(*m))) { - make_meter_marker (&*m, meter_marks.end()); - } - - ++m; + if (!dynamic_cast (&m)) { + make_meter_marker (&m, meter_marks.end()); } } } void -Editor::draw_bbt_marks () +Editor::reset_bbt_marks () { if (!_session) { return; @@ -364,48 +275,15 @@ Editor::draw_bbt_marks () Temporal::TempoMap::SharedPtr tmap (TempoMap::use()); TempoMap::MusicTimes const & bartimes (tmap->bartimes()); - TempoMap::MusicTimes::const_iterator m = bartimes.begin(); - Marks::iterator mm = bbt_marks.begin(); - while (m != bartimes.end() && mm != bbt_marks.end()) { - - Temporal::Point const & mark_point ((*mm)->point()); - Temporal::MusicTimePoint const & metric_point (*m); - - if (mark_point.sclock() < metric_point.sclock()) { - - /* advance through markers, deleting the unused ones */ - - delete *mm; - mm = bbt_marks.erase (mm); - - } else if (metric_point.sclock() < mark_point.sclock()) { - - make_bbt_marker (&metric_point, mm); - ++m; - - } else { - /* marker represents an existing point, update text, properties etc */ - /* XXX left/right text stuff */ - // (*mm)->set_name ((*m)->name()); - (*mm)->set_position (m->time()); - ++m; - ++mm; - } + for (auto & b : bbt_marks) { + delete b; } - if ((m == bartimes.end()) && (mm != bbt_marks.end())) { - while (mm != bbt_marks.end()) { - delete *mm; - mm = bbt_marks.erase (mm); - } - } + bbt_marks.clear (); - if ((mm == bbt_marks.end()) && (m != bartimes.end())) { - while (m != bartimes.end()) { - make_bbt_marker (&*m, bbt_marks.end()); - ++m; - } + for (auto const & b : bartimes) { + make_bbt_marker (&b, bbt_marks.end()); } } @@ -427,7 +305,8 @@ Editor::update_tempo_curves (double min_tempo, double max_tempo, samplecnt_t sr) ++tmp; TempoCurve& curve (tm->curve()); - curve.the_item().lower_to_bottom (); + // std::cerr << "loworing [" << curve.the_item().whoami() << " to bottom\n"; + // curve.the_item().lower_to_bottom (); curve.set_max_tempo (max_tempo); curve.set_min_tempo (min_tempo); @@ -467,17 +346,13 @@ Editor::tempo_map_changed () } } - tempo_map_visual_update (); + tempo_map_model_update (); } void -Editor::tempo_map_visual_update () +Editor::tempo_map_model_update () { - TempoMap::Metrics metrics; - TempoMap::use()->get_metrics (metrics); - - draw_metric_marks (metrics); - draw_tempo_marks (); + reset_metric_marks (); update_tempo_based_rulers (); maybe_draw_grid_lines (); } @@ -858,10 +733,38 @@ Editor::abort_tempo_map_edit () } void -Editor::mid_tempo_change () +Editor::mid_tempo_change (MidTempoChanges what_changed) { // std::cerr << "============== MID TEMPO\n"; // TempoMap::SharedPtr map (TempoMap::use()); // map->dump (std::cerr); - tempo_map_visual_update (); + + if (what_changed & TempoChanged) { + double min_tempo = DBL_MAX; + double max_tempo = 0.0; + + for (auto & t : tempo_marks) { + t->update (); + + TempoMarker* tm (dynamic_cast (t)); + + max_tempo = max (max_tempo, tm->tempo().note_types_per_minute()); + max_tempo = max (max_tempo, tm->tempo().end_note_types_per_minute()); + min_tempo = min (min_tempo, tm->tempo().note_types_per_minute()); + min_tempo = min (min_tempo, tm->tempo().end_note_types_per_minute()); + + } + update_tempo_curves (min_tempo, max_tempo, _session->sample_rate()); + } + + for (auto & m : meter_marks) { + m->update (); + } + + for (auto & b : bbt_marks) { + b->update (); + } + + update_tempo_based_rulers (); + maybe_draw_grid_lines (); } diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 196bcbc572..9de6d34775 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -292,7 +292,7 @@ ArdourMarker::ArdourMarker (PublicEditor& ed, ArdourCanvas::Item& parent, guint3 _pcue->hide(); _pmark->show(); } - + /* setup name pixbuf sizes */ name_font = get_font_for_style (N_("MarkerText")); @@ -669,6 +669,7 @@ TempoMarker::TempoMarker (PublicEditor& editor, ArdourCanvas::Item& parent, guin group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_tempo_marker_event), group, this)); /* points[1].x gives the width of the marker */ _curve = new TempoCurve (editor, *group, curve_color, temp, true, (*points)[1].x); + _curve->the_item().lower_to_bottom (); } TempoMarker::~TempoMarker () @@ -676,6 +677,12 @@ TempoMarker::~TempoMarker () delete _curve; } +void +TempoMarker::update () +{ + set_position (_tempo->time()); +} + TempoCurve& TempoMarker::curve() { @@ -707,6 +714,12 @@ MeterMarker::~MeterMarker () { } +void +MeterMarker::update () +{ + set_position (_meter->time()); +} + void MeterMarker::reset_meter (Temporal::MeterPoint const & m) { @@ -732,6 +745,12 @@ BBTMarker::~BBTMarker () { } +void +BBTMarker::update () +{ + set_position (_point->time()); +} + void BBTMarker::reset_point (Temporal::MusicTimePoint const & p) { diff --git a/gtk2_ardour/marker.h b/gtk2_ardour/marker.h index ed4e8fd7fc..8479313df8 100644 --- a/gtk2_ardour/marker.h +++ b/gtk2_ardour/marker.h @@ -173,6 +173,7 @@ class MetricMarker : public ArdourMarker public: MetricMarker (PublicEditor& ed, ArdourCanvas::Item& parent, guint32 rgba, const std::string& annotation, Type type, Temporal::timepos_t const & pos, bool handle_events); virtual Temporal::Point const & point() const = 0; + virtual void update() = 0; }; class TempoMarker : public MetricMarker @@ -182,6 +183,7 @@ class TempoMarker : public MetricMarker ~TempoMarker (); void reset_tempo (Temporal::TempoPoint const & t); + void update (); Temporal::TempoPoint const & tempo() const { return *_tempo; } Temporal::Point const & point() const; @@ -200,6 +202,7 @@ class MeterMarker : public MetricMarker ~MeterMarker (); void reset_meter (Temporal::MeterPoint const & m); + void update (); Temporal::MeterPoint const & meter() const { return *_meter; } Temporal::Point const & point() const; @@ -215,6 +218,7 @@ class BBTMarker : public MetricMarker ~BBTMarker (); void reset_point (Temporal::MusicTimePoint const &); + void update (); Temporal::MusicTimePoint const & mt_point() const { return *_point; } Temporal::Point const & point() const;