diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 170a421ad5..2e1c13b487 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -196,8 +196,6 @@ AudioRegionView::init (Gdk::Color& basic_color, bool wfd) fade_in_active_changed (); fade_out_active_changed (); - _region->StateChanged.connect (mem_fun(*this, &AudioRegionView::region_changed)); - fade_in_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this)); fade_in_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this)); fade_out_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this)); @@ -325,19 +323,8 @@ AudioRegionView::region_scale_amplitude_changed () void AudioRegionView::region_renamed () { - // FIXME: ugly duplication with RegionView... + Glib::ustring str = RegionView::make_name (); - string str; - - if (_region->locked()) { - str += '>'; - str += _region->name(); - str += '<'; - } else { - str = _region->name(); - } - - // ... because of this if (audio_region()->speed_mismatch (trackview.session().frame_rate())) { str = string ("*") + str; } diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index c46a050ea7..6ed5561804 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1489,13 +1489,16 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items) items.push_back (MenuElem (_("Lock"), bind (mem_fun (*this, &Editor::set_region_lock), true))); items.push_back (MenuElem (_("Unlock"), bind (mem_fun (*this, &Editor::set_region_lock), false))); + items.push_back (MenuElem (_("Lock Position"), bind (mem_fun (*this, &Editor::set_region_position_lock), true))); + items.push_back (MenuElem (_("Unlock Position"), bind (mem_fun (*this, &Editor::set_region_position_lock), false))); items.push_back (MenuElem (_("Mute"), bind (mem_fun (*this, &Editor::set_region_mute), true))); items.push_back (MenuElem (_("Unmute"), bind (mem_fun (*this, &Editor::set_region_mute), false))); items.push_back (MenuElem (_("Opaque"), bind (mem_fun (*this, &Editor::set_region_opaque), true))); items.push_back (MenuElem (_("Transparent"), bind (mem_fun (*this, &Editor::set_region_opaque), false))); /* We allow "Original position" if at least one region is not at its - natural position */ + natural position + */ RegionSelection::iterator i = selection->regions.begin(); while (i != selection->regions.end() && (*i)->region()->at_natural_position() == true) { ++i; diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 66d2aa4335..51403c2992 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -868,6 +868,7 @@ class Editor : public PublicEditor void reset_point_selection (); void set_region_mute (bool); void set_region_lock (bool); + void set_region_position_lock (bool); void set_region_opaque (bool); void raise_region (); void raise_region_to_top (); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index e2be04a570..4f06562fb0 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -3387,10 +3387,9 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event rv = (*i); - if (rv->region()->locked()) { + if (!rv->region()->can_move()) { continue; } - if (regionview_x_movement) { double ownspeed = 1.0; @@ -3445,10 +3444,6 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event selection->add (latest_regionview); } - /* if the original region was locked, we don't care for the new one */ - - newregion->set_locked (false); - } else { /* just change the model */ diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 46443c20e9..64884c358b 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -3454,12 +3454,18 @@ void Editor::set_region_lock (bool yn) { for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - AudioRegionView* const arv = dynamic_cast(*i); - if (arv) { - if (arv->audio_region()->locked() != yn) { - arv->audio_region()->set_locked (yn); - } - } + (*i)->region()->set_locked (yn); + } +} + +/** Set the position-locked state of all selected regions to a particular value. + * @param yn true to make locked, false to make unlocked. + */ +void +Editor::set_region_position_lock (bool yn) +{ + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + (*i)->region()->set_position_locked (yn); } } @@ -3467,12 +3473,7 @@ void Editor::set_region_mute (bool yn) { for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - AudioRegionView* const arv = dynamic_cast(*i); - if (arv) { - if (arv->audio_region()->muted() != yn) { - arv->audio_region()->set_muted (yn); - } - } + (*i)->region()->set_muted (yn); } } @@ -3480,12 +3481,7 @@ void Editor::set_region_opaque (bool yn) { for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - AudioRegionView* const arv = dynamic_cast(*i); - if (arv) { - if (arv->audio_region()->opaque() != yn) { - arv->audio_region()->set_opaque (yn); - } - } + (*i)->region()->set_opaque (yn); } } diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index 24e476704a..859e2edfb4 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -405,26 +405,37 @@ RegionView::hide_region_editor() } } -void -RegionView::region_renamed () +Glib::ustring +RegionView::make_name () const { - string str; + Glib::ustring str; + + // XXX nice to have some good icons for this if (_region->locked()) { str += '>'; str += _region->name(); str += '<'; + } else if (_region->position_locked()) { + str += '{'; + str += _region->name(); + str += '}'; } else { str = _region->name(); } - // speed mismatch handled in audio_region_view.cc - // FIXME: come up with more elegant solution for this - if (_region->muted()) { str = string ("!") + str; } + return str; +} + +void +RegionView::region_renamed () +{ + Glib::ustring str = make_name (); + set_item_name (str, this); set_name_text (str); reset_width_dependent_items (_pixel_width); @@ -483,7 +494,7 @@ RegionView::region_sync_changed () void RegionView::move (double x_delta, double y_delta) { - if (_region->locked() || (x_delta == 0 && y_delta == 0)) { + if (!_region->can_move() || (x_delta == 0 && y_delta == 0)) { return; } diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h index 636abc031c..0f4d57ad04 100644 --- a/gtk2_ardour/region_view.h +++ b/gtk2_ardour/region_view.h @@ -111,6 +111,8 @@ class RegionView : public TimeAxisViewItem virtual void region_renamed (); void region_sync_changed (); + Glib::ustring make_name () const; + static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*); void lock_toggle (); diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 012fd9ce96..9a00498371 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -66,6 +66,7 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro RightOfSplit = 0x8000, Hidden = 0x10000, DoNotSaveState = 0x20000, + PositionLocked = 0x40000, // range_guarantoor = USHRT_MAX }; @@ -111,9 +112,11 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro bool muted() const { return _flags & Muted; } bool opaque () const { return _flags & Opaque; } bool locked() const { return _flags & Locked; } + bool position_locked() const { return _flags & PositionLocked; } bool automatic() const { return _flags & Automatic; } bool whole_file() const { return _flags & WholeFile ; } bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); } + bool can_move() const { return !(_flags & (Locked|PositionLocked)); } virtual bool should_save_state () const { return !(_flags & DoNotSaveState); }; @@ -163,6 +166,7 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro void set_muted (bool yn); void set_opaque (bool yn); void set_locked (bool yn); + void set_position_locked (bool yn); virtual uint32_t read_data_count() const { return _read_data_count; } diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 345fbe771d..389a88f295 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -330,6 +330,7 @@ setup_enum_writer () REGISTER_CLASS_ENUM (Region, DefaultFadeIn); REGISTER_CLASS_ENUM (Region, DefaultFadeOut); REGISTER_CLASS_ENUM (Region, Locked); + REGISTER_CLASS_ENUM (Region, PositionLocked); REGISTER_CLASS_ENUM (Region, Automatic); REGISTER_CLASS_ENUM (Region, WholeFile); REGISTER_CLASS_ENUM (Region, FadeIn); diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index e5125d8629..d8a98ecefe 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -111,7 +111,7 @@ Region::Region (SourceList& srcs, nframes_t start, nframes_t length, const strin Region::Region (boost::shared_ptr other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) : _name(name) , _type(other->data_type()) - , _flags(Flag(flags & ~(Locked|WholeFile|Hidden))) + , _flags(Flag(flags & ~(Locked|PositionLocked|WholeFile|Hidden))) , _start(other->_start + offset) , _length(length) , _position(0) @@ -152,7 +152,7 @@ Region::Region (boost::shared_ptr other, nframes_t offset, nframes Region::Region (boost::shared_ptr other) : _name(other->_name) , _type(other->data_type()) - , _flags(Flag(other->_flags & ~Locked)) + , _flags(Flag(other->_flags & ~(Locked|PositionLocked))) , _start(other->_start) , _length(other->_length) , _position(other->_position) @@ -415,7 +415,7 @@ Region::special_set_position (nframes_t pos) void Region::set_position (nframes_t pos, void *src) { - if (_flags & Locked) { + if (!can_move()) { return; } @@ -495,7 +495,7 @@ Region::nudge_position (long n, void *src) void Region::set_start (nframes_t pos, void *src) { - if (_flags & Locked) { + if (_flags & (Locked|PositionLocked)) { return; } /* This just sets the start, nothing else. It effectively shifts @@ -520,7 +520,7 @@ Region::set_start (nframes_t pos, void *src) void Region::trim_start (nframes_t new_position, void *src) { - if (_flags & Locked) { + if (_flags & (Locked|PositionLocked)) { return; } nframes_t new_start; @@ -756,6 +756,19 @@ Region::set_locked (bool yn) } } +void +Region::set_position_locked (bool yn) +{ + if (position_locked() != yn) { + if (yn) { + _flags = Flag (_flags|PositionLocked); + } else { + _flags = Flag (_flags & ~PositionLocked); + } + send_change (LockChanged); + } +} + void Region::set_sync_position (nframes_t absolute_pos) {