Import libfluidsynth into the Ardour codebase
[ardour.git] / gtk2_ardour / editor_regions.cc
index c6620958c6b31786cff44489a976a3a645b88804..845e56fdec5cb00e852a04b61123c0dde6f089bb 100644 (file)
@@ -52,7 +52,7 @@
 #include "tooltips.h"
 #include "ui_config.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
@@ -95,38 +95,49 @@ EditorRegions::EditorRegions (Editor* e)
        _model->set_sort_func (0, sigc::mem_fun (*this, &EditorRegions::sorter));
        _model->set_sort_column (0, SORT_ASCENDING);
 
+       /* column widths */
+       int bbt_width, sync_width, check_width, height;
+
+       Glib::RefPtr<Pango::Layout> layout = _display.create_pango_layout (X_("000|000|000"));
+       Gtkmm2ext::get_pixel_size (layout, bbt_width, height);
+
+       layout = _display.create_pango_layout (X_("Start "));
+       Gtkmm2ext::get_pixel_size (layout, sync_width, height);
+
+       check_width = 20;
+
        TreeViewColumn* col_name = manage (new TreeViewColumn ("", _columns.name));
        col_name->set_fixed_width (120);
        col_name->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_position = manage (new TreeViewColumn ("", _columns.position));
-       col_position->set_fixed_width (68);
+       col_position->set_fixed_width (bbt_width);
        col_position->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_end = manage (new TreeViewColumn ("", _columns.end));
-       col_end->set_fixed_width (68);
+       col_end->set_fixed_width (bbt_width);
        col_end->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_length = manage (new TreeViewColumn ("", _columns.length));
-       col_length->set_fixed_width (68);
+       col_length->set_fixed_width (bbt_width);
        col_length->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_sync = manage (new TreeViewColumn ("", _columns.sync));
-       col_sync->set_fixed_width (38);
+       col_sync->set_fixed_width (sync_width);
        col_sync->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_fadein = manage (new TreeViewColumn ("", _columns.fadein));
-       col_fadein->set_fixed_width (68);
+       col_fadein->set_fixed_width (bbt_width);
        col_fadein->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_fadeout = manage (new TreeViewColumn ("", _columns.fadeout));
-       col_fadeout->set_fixed_width (68);
+       col_fadeout->set_fixed_width (bbt_width);
        col_fadeout->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_locked = manage (new TreeViewColumn ("", _columns.locked));
-       col_locked->set_fixed_width (20);
+       col_locked->set_fixed_width (check_width);
        col_locked->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_glued = manage (new TreeViewColumn ("", _columns.glued));
-       col_glued->set_fixed_width (20);
+       col_glued->set_fixed_width (check_width);
        col_glued->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_muted = manage (new TreeViewColumn ("", _columns.muted));
-       col_muted->set_fixed_width (20);
+       col_muted->set_fixed_width (check_width);
        col_muted->set_sizing (TREE_VIEW_COLUMN_FIXED);
        TreeViewColumn* col_opaque = manage (new TreeViewColumn ("", _columns.opaque));
-       col_opaque->set_fixed_width (20);
+       col_opaque->set_fixed_width (check_width);
        col_opaque->set_sizing (TREE_VIEW_COLUMN_FIXED);
 
        _display.append_column (*col_name);
@@ -255,6 +266,8 @@ EditorRegions::EditorRegions (Editor* e)
        ARDOUR::Region::RegionPropertyChanged.connect (region_property_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::region_changed, this, _1, _2), gui_context());
        ARDOUR::RegionFactory::CheckNewRegion.connect (check_new_region_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::add_region, this, _1), gui_context());
 
+       e->EditorFreeze.connect (editor_freeze_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::freeze_tree_model, this), gui_context());
+       e->EditorThaw.connect (editor_thaw_connection, MISSING_INVALIDATOR, boost::bind (&EditorRegions::thaw_tree_model, this), gui_context());
 }
 
 bool
@@ -470,8 +483,8 @@ EditorRegions::add_region (boost::shared_ptr<Region> region)
        row[_columns.region] = region;
 
        region_row_map.insert(pair<boost::shared_ptr<ARDOUR::Region>, Gtk::TreeModel::RowReference>(region, TreeRowReference(_model, TreePath (row))) );
-
-       populate_row(region, (*row));
+       PropertyChange pc;
+       populate_row(region, (*row), pc);
 }
 
 void
@@ -519,14 +532,13 @@ EditorRegions::region_changed (boost::shared_ptr<Region> r, const PropertyChange
        our_interests.add (ARDOUR::Properties::fade_out_active);
 
        if (what_changed.contains (our_interests)) {
-
                if (last_row != 0) {
 
                        TreeModel::iterator j = _model->get_iter (last_row.get_path());
                        boost::shared_ptr<Region> c = (*j)[_columns.region];
 
                        if (c == r) {
-                               populate_row (r, (*j));
+                               populate_row (r, (*j), what_changed);
 
                                if (what_changed.contains (ARDOUR::Properties::hidden)) {
                                        redisplay ();
@@ -546,7 +558,7 @@ EditorRegions::region_changed (boost::shared_ptr<Region> r, const PropertyChange
                        boost::shared_ptr<Region> c = (*j)[_columns.region];
 
                        if (c == r) {
-                               populate_row (r, (*j));
+                               populate_row (r, (*j), what_changed);
 
                                if (what_changed.contains (ARDOUR::Properties::hidden)) {
                                        redisplay ();
@@ -685,9 +697,9 @@ EditorRegions::update_row (boost::shared_ptr<Region> region)
        it = region_row_map.find (region);
 
        if (it != region_row_map.end()){
-
+               PropertyChange c;
                TreeModel::iterator j = _model->get_iter ((*it).second.get_path());
-               populate_row(region, (*j));
+               populate_row(region, (*j), c);
        }
 }
 
@@ -707,7 +719,8 @@ EditorRegions::update_all_rows ()
                boost::shared_ptr<Region> region = (*j)[_columns.region];
 
                if (!region->automatic()) {
-                       populate_row(region, (*j));
+                       PropertyChange c;
+                       populate_row(region, (*j), c);
                }
        }
 }
@@ -726,7 +739,7 @@ EditorRegions::format_position (framepos_t pos, char* buf, size_t bufsize, bool
 
        switch (ARDOUR_UI::instance()->secondary_clock->mode ()) {
        case AudioClock::BBT:
-               _session->tempo_map().bbt_time (pos, bbt);
+               bbt = _session->tempo_map().bbt_at_frame (pos);
                if (onoff) {
                        snprintf (buf, bufsize, "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
                } else {
@@ -774,26 +787,53 @@ EditorRegions::format_position (framepos_t pos, char* buf, size_t bufsize, bool
 }
 
 void
-EditorRegions::populate_row (boost::shared_ptr<Region> region, TreeModel::Row const &row)
+EditorRegions::populate_row (boost::shared_ptr<Region> region, TreeModel::Row const &row, PBD::PropertyChange const &what_changed)
 {
        boost::shared_ptr<AudioRegion> audioregion = boost::dynamic_pointer_cast<AudioRegion>(region);
        //uint32_t used = _session->playlists->region_use_count (region);
        /* Presently a region is only used once so let's save on the sequential scan to determine use count */
        uint32_t used = 1;
 
-       populate_row_position (region, row, used);
-       populate_row_end (region, row, used);
-       populate_row_sync (region, row, used);
-       populate_row_fade_in (region, row, used, audioregion);
-       populate_row_fade_out (region, row, used, audioregion);
-       populate_row_locked (region, row, used);
-       populate_row_glued (region, row, used);
-       populate_row_muted (region, row, used);
-       populate_row_opaque (region, row, used);
-       populate_row_length (region, row);
-       populate_row_source (region, row);
-       populate_row_name (region, row);
-       populate_row_used (region, row, used);
+       PropertyChange c;
+       const bool all = what_changed == c;
+
+       if (all || what_changed.contains (Properties::position)) {
+               populate_row_position (region, row, used);
+       }
+       if (all || what_changed.contains (Properties::start)) {
+               populate_row_sync (region, row, used);
+       }
+       if (all || what_changed.contains (Properties::fade_in)) {
+               populate_row_fade_in (region, row, used, audioregion);
+       }
+       if (all || what_changed.contains (Properties::fade_out)) {
+               populate_row_fade_out (region, row, used, audioregion);
+       }
+       if (all || what_changed.contains (Properties::locked)) {
+               populate_row_locked (region, row, used);
+       }
+       if (all || what_changed.contains (Properties::position_lock_style)) {
+               populate_row_glued (region, row, used);
+       }
+       if (all || what_changed.contains (Properties::muted)) {
+               populate_row_muted (region, row, used);
+       }
+       if (all || what_changed.contains (Properties::opaque)) {
+               populate_row_opaque (region, row, used);
+       }
+       if (all || what_changed.contains (Properties::length)) {
+               populate_row_end (region, row, used);
+               populate_row_length (region, row);
+       }
+       if (all) {
+               populate_row_source (region, row);
+       }
+       if (all || what_changed.contains (Properties::name)) {
+               populate_row_name (region, row);
+       }
+       if (all) {
+               populate_row_used (region, row, used);
+       }
 }
 
 #if 0
@@ -839,7 +879,15 @@ void
 EditorRegions::populate_row_length (boost::shared_ptr<Region> region, TreeModel::Row const &row)
 {
        char buf[16];
-       format_position (region->length(), buf, sizeof (buf));
+
+       if (ARDOUR_UI::instance()->secondary_clock->mode () == AudioClock::BBT) {
+               TempoMap& map (_session->tempo_map());
+               Timecode::BBT_Time bbt = map.bbt_at_beat (map.beat_at_frame (region->last_frame()) - map.beat_at_frame (region->first_frame()));
+               snprintf (buf, sizeof (buf), "%03d|%02d|%04d" , bbt.bars, bbt.beats, bbt.ticks);
+       } else {
+               format_position (region->length(), buf, sizeof (buf));
+       }
+
        row[_columns.length] = buf;
 }
 
@@ -1406,6 +1454,25 @@ EditorRegions::get_single_selection ()
        return (*iter)[_columns.region];
 }
 
+void
+EditorRegions::freeze_tree_model (){
+
+       _display.set_model (Glib::RefPtr<Gtk::TreeStore>(0));
+       _model->set_sort_column (-2, SORT_ASCENDING); //Disable sorting to gain performance
+
+}
+
+void
+EditorRegions::thaw_tree_model (){
+
+       _model->set_sort_column (0, SORT_ASCENDING); // renabale sorting
+       _display.set_model (_model);
+
+       if (toggle_full_action()->get_active()) {
+               _display.expand_all();
+       }
+}
+
 void
 EditorRegions::locked_changed (std::string const & path)
 {