_session->StepEditStatusChange.connect (_session_connections, invalidator (*this), boost::bind (&Editor::step_edit_status_change, this, _1), gui_context());
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&Editor::map_transport_state, this), gui_context());
_session->PositionChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::map_position_change, this, _1), gui_context());
- _session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Editor::handle_new_route, this, _1), gui_context());
+ _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->Located.connect (_session_connections, invalidator (*this), boost::bind (&Editor::located, this), gui_context());
/** Pop up a context menu for when the user clicks on a start crossfade */
void
-Editor::popup_xfade_in_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType item_type)
+Editor::popup_xfade_in_context_menu (int button, int32_t time, ArdourCanvas::Item* /*item*/, ItemType /*item_type*/)
{
using namespace Menu_Helpers;
/** Pop up a context menu for when the user clicks on an end crossfade */
void
-Editor::popup_xfade_out_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType item_type)
+Editor::popup_xfade_out_context_menu (int button, int32_t time, ArdourCanvas::Item* /*item*/, ItemType /*item_type*/)
{
using namespace Menu_Helpers;
edit_items.push_back (SeparatorElem());
edit_items.push_back (MenuElem (_("Crop Region to Range"), sigc::mem_fun(*this, &Editor::crop_region_to_selection)));
edit_items.push_back (MenuElem (_("Fill Range with Region"), sigc::mem_fun(*this, &Editor::region_fill_selection)));
- edit_items.push_back (MenuElem (_("Duplicate Range"), sigc::bind (sigc::mem_fun(*this, &Editor::duplicate_dialog), false)));
+ edit_items.push_back (MenuElem (_("Duplicate Range"), sigc::bind (sigc::mem_fun(*this, &Editor::duplicate_range), false)));
edit_items.push_back (SeparatorElem());
edit_items.push_back (MenuElem (_("Consolidate Range"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), true, false)));
_session->locations()->marks_either_side (start, before, after);
- if (before == max_framepos) {
+ if (before == max_framepos && after == max_framepos) {
+ /* No marks to snap to, so just don't snap */
+ return;
+ } else if (before == max_framepos) {
start = after;
} else if (after == max_framepos) {
start = before;
const char* q;
p = (const char *) malloc (txt.length() + 1);
- txt.copy ((char *) p, txt.length(), 0);
- ((char*)p)[txt.length()] = '\0';
+ txt.copy (const_cast<char *> (p), txt.length(), 0);
+ const_cast<char*>(p)[txt.length()] = '\0';
while (p)
{
}
void
-Editor::duplicate_dialog (bool with_dialog)
+Editor::duplicate_range (bool with_dialog)
{
float times = 1.0f;
int
Editor::idle_visual_changer ()
{
+ /* set_horizontal_position() below (and maybe other calls) call
+ gtk_main_iteration(), so it's possible that a signal will be handled
+ half-way through this method. If this signal wants an
+ idle_visual_changer we must schedule another one after this one, so
+ mark the idle_handler_id as -1 here to allow that. Also make a note
+ that we are doing the visual change, so that changes in response to
+ super-rapid-screen-update can be dropped if we are still processing
+ the last one.
+ */
+ pending_visual_change.idle_handler_id = -1;
+ pending_visual_change.being_handled = true;
+
VisualChange::Type p = pending_visual_change.pending;
pending_visual_change.pending = (VisualChange::Type) 0;
_summary->set_overlays_dirty ();
- pending_visual_change.idle_handler_id = -1;
+ pending_visual_change.being_handled = false;
return 0; /* this is always a one-shot call */
}
Location* tpl;
if ((tpl = transport_punch_location()) == 0) {
- Location* loc = new Location (*_session, start, end, _("Loop"), Location::IsAutoPunch);
+ Location* loc = new Location (*_session, start, end, _("Punch"), Location::IsAutoPunch);
XMLNode &before = _session->locations()->get_state();
_session->locations()->add (loc, true);
_session->set_auto_loop_location (loc);
return t;
}
-
void
-Editor::handle_new_route (RouteList& routes)
+Editor::add_routes (RouteList& routes)
{
ENSURE_GUI_THREAD (*this, &Editor::handle_new_route, routes)
if (!_stationary_playhead) {
- if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0) {
+ if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0 && !pending_visual_change.being_handled) {
+ /* We only do this if we aren't already
+ handling a visual change (ie if
+ pending_visual_change.being_handled is
+ false) so that these requests don't stack
+ up there are too many of them to handle in
+ time.
+ */
reset_x_origin_to_follow_playhead ();
}