merge fix

This commit is contained in:
Ben Loftis 2015-07-16 16:13:24 -05:00
commit 46c8369328
26 changed files with 611 additions and 255 deletions

View file

@ -1261,7 +1261,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
trackview.session()->add_command (new MementoCommand<AudioRegion>(*(audio_region().get()), &region_before, &region_after));
}
audio_region()->envelope()->add (fx, y, with_guard_points);
audio_region()->envelope()->editor_add (fx, y, with_guard_points);
XMLNode &after = audio_region()->envelope()->get_state();
trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));

View file

@ -41,6 +41,7 @@
#include "tape_region_view.h"
#include "audio_time_axis.h"
#include "region_selection.h"
#include "region_gain_line.h"
#include "selection.h"
#include "public_editor.h"
#include "ardour_ui.h"
@ -471,3 +472,14 @@ AudioStreamView::color_handler ()
}
}
}
void
AudioStreamView::set_selected_points (PointSelection& points)
{
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv && arv->get_gain_line ()) {
arv->get_gain_line ()->set_selected_points (points);
}
}
}

View file

@ -26,6 +26,7 @@
#include <boost/weak_ptr.hpp>
#include "ardour/location.h"
#include "point_selection.h"
#include "editing.h"
#include "streamview.h"
@ -61,6 +62,7 @@ class AudioStreamView : public StreamView
std::pair<std::list<AudioRegionView*>, std::list<AudioRegionView*> > hide_xfades_with (boost::shared_ptr<ARDOUR::AudioRegion> ar);
RegionView* create_region_view (boost::shared_ptr<ARDOUR::Region>, bool, bool);
void set_selected_points (PointSelection&);
private:
void setup_rec_box ();

View file

@ -204,7 +204,7 @@ AutomationController::toggled ()
_controllable->set_automation_state(Write);
}
if (_controllable->list()) {
_controllable->list()->set_in_write_pass(true, false, _controllable->session().audible_frame());
_controllable->list()->set_in_write_pass(true, true, _controllable->session().audible_frame());
}
}
const bool was_active = _controllable->get_value() >= 0.5;

View file

@ -466,7 +466,6 @@ AutomationLine::string_to_fraction (string const & s) const
void
AutomationLine::start_drag_single (ControlPoint* cp, double x, float fraction)
{
trackview.editor().begin_reversible_command (_("automation event move"));
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder(), &get_state(), 0));
@ -492,7 +491,6 @@ AutomationLine::start_drag_single (ControlPoint* cp, double x, float fraction)
void
AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
{
trackview.editor().begin_reversible_command (_("automation range move"));
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder (), &get_state(), 0));
@ -512,7 +510,6 @@ AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
void
AutomationLine::start_drag_multiple (list<ControlPoint*> cp, float fraction, XMLNode* state)
{
trackview.editor().begin_reversible_command (_("automation range move"));
trackview.editor().session()->add_command (
new MementoCommand<AutomationList> (memento_command_binder(), state, 0));
@ -678,6 +675,7 @@ AutomationLine::drag_motion (double const x, float fraction, bool ignore_x, bool
for (vector<CCP>::iterator ccp = contiguous_points.begin(); ccp != contiguous_points.end(); ++ccp) {
(*ccp)->compute_x_bounds (trackview.editor());
}
_drag_had_movement = true;
}
/* OK, now on to the stuff related to *this* motion event. First, for
@ -738,7 +736,6 @@ AutomationLine::drag_motion (double const x, float fraction, bool ignore_x, bool
_drag_distance += dx;
_drag_x += dx;
_last_drag_fraction = fraction;
_drag_had_movement = true;
did_push = with_push;
return pair<double, float> (_drag_x + dx, _last_drag_fraction + dy);
@ -951,7 +948,8 @@ AutomationLine::set_selected_points (PointSelection const & points)
set_colors ();
}
void AutomationLine::set_colors ()
void
AutomationLine::set_colors ()
{
set_line_color (ARDOUR_UI::config()->color ("automation line"));
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {

View file

@ -190,7 +190,7 @@ AutomationRegionView::add_automation_event (GdkEvent *, framepos_t when, double
view->editor().begin_reversible_command (_("add automation event"));
XMLNode& before = _line->the_list()->get_state();
_line->the_list()->add (when_d, y, with_guard_points, false);
_line->the_list()->editor_add (when_d, y, with_guard_points);
XMLNode& after = _line->the_list()->get_state();

View file

@ -449,7 +449,7 @@ AutomationTimeAxisView::clear_clicked ()
} else if (_view) {
_view->clear ();
}
set_automation_state ((AutoState) ARDOUR::Off);
_editor.commit_reversible_command ();
_session->set_dirty ();
}
@ -644,10 +644,10 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when,
_editor.begin_reversible_command (_("add automation event"));
XMLNode& before = list->get_state();
list->add (when, y, with_guard_points);
list->editor_add (when, y, with_guard_points);
XMLNode& after = list->get_state();
_session->add_command (new MementoCommand<ARDOUR::AutomationList> (*list, &before, &after));
_session->add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
_editor.commit_reversible_command ();
_session->set_dirty ();
}

View file

@ -1236,7 +1236,7 @@ Editor::which_canvas_cursor(ItemType type) const
cursor = _cursors->fader;
break;
case GainLineItem:
cursor = which_track_cursor ();
cursor = _cursors->cross_hair;
break;
case AutomationLineItem:
cursor = _cursors->cross_hair;

View file

@ -695,6 +695,11 @@ Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, Automation
type = AutomationLineItem;
}
clicked_control_point = 0;
clicked_axisview = &al->trackview;
clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
clicked_regionview = 0;
return typed_event (item, event, type);
}

View file

@ -617,6 +617,11 @@ RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
assert(_last_pointer_time_axis_view >= 0);
_last_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second;
}
if (_brushing) {
/* cross track dragging seems broken here. disabled for now. */
_y_constrained = true;
}
}
double
@ -1221,13 +1226,13 @@ void
RegionMoveDrag::motion (GdkEvent* event, bool first_move)
{
if (_copy && first_move) {
if (_x_constrained) {
if (_x_constrained && !_brushing) {
_editor->begin_reversible_command (Operations::fixed_time_region_copy);
} else {
} else if (!_brushing) {
_editor->begin_reversible_command (Operations::region_copy);
} else if (_brushing) {
_editor->begin_reversible_command (Operations::drag_region_brush);
}
/* duplicate the regionview(s) and region(s) */
list<DraggingView> new_regionviews;
@ -1285,14 +1290,14 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move)
}
} else if (!_copy && first_move) {
if (_x_constrained) {
if (_x_constrained && !_brushing) {
_editor->begin_reversible_command (_("fixed time region drag"));
} else {
} else if (!_brushing) {
_editor->begin_reversible_command (Operations::region_drag);
} else if (_brushing) {
_editor->begin_reversible_command (Operations::drag_region_brush);
}
}
RegionMotionDrag::motion (event, first_move);
}
@ -1500,12 +1505,6 @@ RegionMoveDrag::finished_no_copy (
set<RouteTimeAxisView*> views_to_update;
RouteTimeAxisView* new_time_axis_view = 0;
if (_brushing) {
/* all changes were made during motion event handlers */
_editor->commit_reversible_command ();
return;
}
typedef map<boost::shared_ptr<Playlist>, RouteTimeAxisView*> PlaylistMapping;
PlaylistMapping playlist_mapping;
@ -1619,7 +1618,6 @@ RegionMoveDrag::finished_no_copy (
}
rv->region()->set_position (where);
_editor->session()->add_command (new StatefulDiffCommand (rv->region()));
}
@ -1668,7 +1666,7 @@ RegionMoveDrag::finished_no_copy (
/* write commands for the accumulated diffs for all our modified playlists */
add_stateful_diff_commands_for_playlists (modified_playlists);
/* applies to _brushing */
_editor->commit_reversible_command ();
/* We have futzed with the layering of canvas items on our streamviews.
@ -2334,6 +2332,8 @@ RegionCreateDrag::aborted (bool)
NoteResizeDrag::NoteResizeDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
, region (0)
, relative (false)
, at_front (true)
, _snap_delta (0)
{
DEBUG_TRACE (DEBUG::Drags, "New NoteResizeDrag\n");
@ -2370,37 +2370,36 @@ NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*ignored*/)
} else {
relative = true;
}
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
if (ms.size() > 1) {
/* has to be relative, may make no sense otherwise */
relative = true;
}
/* select this note; if it is already selected, preserve the existing selection,
otherwise make this note the only one selected.
*/
region->note_selected (cnote, cnote->selected ());
_editor->begin_reversible_command (_("resize notes"));
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ) {
MidiRegionSelection::iterator next;
next = r;
++next;
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
if (mrv) {
mrv->begin_resizing (at_front);
}
r = next;
}
}
void
NoteResizeDrag::motion (GdkEvent* event, bool /*first_move*/)
NoteResizeDrag::motion (GdkEvent* event, bool first_move)
{
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
if (first_move) {
_editor->begin_reversible_command (_("resize notes"));
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ) {
MidiRegionSelection::iterator next;
next = r;
++next;
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*r);
if (mrv) {
mrv->begin_resizing (at_front);
}
r = next;
}
}
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
NoteBase* nb = reinterpret_cast<NoteBase*> (_item->get_data ("notebase"));
assert (nb);
@ -2434,8 +2433,12 @@ NoteResizeDrag::motion (GdkEvent* event, bool /*first_move*/)
}
void
NoteResizeDrag::finished (GdkEvent* event, bool /*movement_occurred*/)
NoteResizeDrag::finished (GdkEvent* event, bool movement_occurred)
{
if (!movement_occurred) {
return;
}
MidiRegionSelection& ms (_editor->get_selection().midi_regions);
for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) {
NoteBase* nb = reinterpret_cast<NoteBase*> (_item->get_data ("notebase"));
@ -2458,9 +2461,11 @@ NoteResizeDrag::finished (GdkEvent* event, bool /*movement_occurred*/)
}
}
}
if (apply_snap_delta) {
sd = _snap_delta;
}
mrv->commit_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative, sd, snap);
}
}
@ -3479,7 +3484,7 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred)
fade_length = pos - region->position();
}
_editor->begin_reversible_command (_("change fade in length"));
bool in_command = false;
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
@ -3495,11 +3500,17 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred)
tmp->audio_region()->set_fade_in_length (fade_length);
tmp->audio_region()->set_fade_in_active (true);
if (!in_command) {
_editor->begin_reversible_command (_("change fade in length"));
in_command = true;
}
XMLNode &after = alist->get_state();
_editor->session()->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
}
_editor->commit_reversible_command ();
if (in_command) {
_editor->commit_reversible_command ();
}
}
void
@ -3598,7 +3609,7 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred)
fade_length = region->last_frame() - pos;
}
_editor->begin_reversible_command (_("change fade out length"));
bool in_command = false;
for (list<DraggingView>::iterator i = _views.begin(); i != _views.end(); ++i) {
@ -3614,11 +3625,17 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred)
tmp->audio_region()->set_fade_out_length (fade_length);
tmp->audio_region()->set_fade_out_active (true);
if (!in_command) {
_editor->begin_reversible_command (_("change fade out length"));
in_command = false;
}
XMLNode &after = alist->get_state();
_editor->session()->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
}
_editor->commit_reversible_command ();
if (in_command) {
_editor->commit_reversible_command ();
}
}
void
@ -3952,8 +3969,8 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->_dragging_edit_point = false;
_editor->begin_reversible_command ( _("move marker") );
XMLNode &before = _editor->session()->locations()->get_state();
bool in_command = false;
MarkerSelection::iterator i;
CopiedLocationInfo::iterator x;
@ -3968,9 +3985,12 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
if (location) {
if (location->locked()) {
return;
continue;
}
if (!in_command) {
_editor->begin_reversible_command ( _("move marker") );
in_command = true;
}
if (location->is_mark()) {
location->set_start (((*x).location)->start());
} else {
@ -3979,9 +3999,11 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
}
}
XMLNode &after = _editor->session()->locations()->get_state();
_editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));
_editor->commit_reversible_command ();
if (in_command) {
XMLNode &after = _editor->session()->locations()->get_state();
_editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));
_editor->commit_reversible_command ();
}
}
void
@ -4044,9 +4066,6 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
setup_snap_delta (pos);
float const fraction = 1 - (_point->get_y() / _point->line().height());
_point->line().start_drag_single (_point, _fixed_grab_x, fraction);
show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction));
_pushing = Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::push_points_modifier ());
@ -4057,7 +4076,7 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
}
void
ControlPointDrag::motion (GdkEvent* event, bool)
ControlPointDrag::motion (GdkEvent* event, bool first_motion)
{
double dx = _drags->current_pointer_x() - last_pointer_x();
double dy = current_pointer_y() - last_pointer_y();
@ -4076,11 +4095,6 @@ ControlPointDrag::motion (GdkEvent* event, bool)
// positive side of zero
double const zero_gain_y = (1.0 - _zero_gain_fraction) * _point->line().height() - .01;
// make sure we hit zero when passing through
if ((cy < zero_gain_y && (cy - dy) > zero_gain_y) || (cy > zero_gain_y && (cy - dy) < zero_gain_y)) {
cy = zero_gain_y;
}
if (_x_constrained) {
cx = _fixed_grab_x;
}
@ -4091,6 +4105,11 @@ ControlPointDrag::motion (GdkEvent* event, bool)
_cumulative_x_drag = cx - _fixed_grab_x;
_cumulative_y_drag = cy - _fixed_grab_y;
// make sure we hit zero when passing through
if ((cy < zero_gain_y && (cy - dy) > zero_gain_y) || (cy > zero_gain_y && (cy - dy) < zero_gain_y)) {
cy = zero_gain_y;
}
cx = max (0.0, cx);
cy = max (0.0, cy);
cy = min ((double) _point->line().height(), cy);
@ -4106,6 +4125,11 @@ ControlPointDrag::motion (GdkEvent* event, bool)
float const fraction = 1.0 - (cy / _point->line().height());
if (first_motion) {
_editor->begin_reversible_command (_("automation event move"));
_point->line().start_drag_single (_point, _fixed_grab_x, fraction);
}
_point->line().drag_motion (_editor->sample_to_pixel_unrounded (cx_frames), fraction, false, _pushing, _final_index);
show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction));
@ -4123,10 +4147,9 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred)
} else {
motion (event, false);
_point->line().end_drag (_pushing, _final_index);
_editor->commit_reversible_command ();
}
_point->line().end_drag (_pushing, _final_index);
_editor->commit_reversible_command ();
}
void
@ -4151,6 +4174,8 @@ LineDrag::LineDrag (Editor* e, ArdourCanvas::Item* i)
: Drag (e, i)
, _line (0)
, _cumulative_y_drag (0)
, _before (0)
, _after (0)
{
DEBUG_TRACE (DEBUG::Drags, "New LineDrag\n");
}
@ -4174,10 +4199,7 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
framecnt_t const frame_within_region = (framecnt_t) floor (cx * _editor->samples_per_pixel);
uint32_t before;
uint32_t after;
if (!_line->control_points_adjacent (frame_within_region, before, after)) {
if (!_line->control_points_adjacent (frame_within_region, _before, _after)) {
/* no adjacent points */
return;
}
@ -4191,13 +4213,11 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
double fraction = 1.0 - (cy / _line->height());
_line->start_drag_line (before, after, fraction);
show_verbose_cursor_text (_line->get_verbose_cursor_string (fraction));
}
void
LineDrag::motion (GdkEvent* event, bool)
LineDrag::motion (GdkEvent* event, bool first_move)
{
double dy = current_pointer_y() - last_pointer_y();
@ -4215,6 +4235,11 @@ LineDrag::motion (GdkEvent* event, bool)
double const fraction = 1.0 - (cy / _line->height());
uint32_t ignored;
if (first_move) {
_editor->begin_reversible_command (_("automation range move"));
_line->start_drag_line (_before, _after, fraction);
}
/* we are ignoring x position for this drag, so we can just pass in anything */
_line->drag_motion (0, fraction, true, false, ignored);
@ -4227,20 +4252,17 @@ LineDrag::finished (GdkEvent* event, bool movement_occured)
if (movement_occured) {
motion (event, false);
_line->end_drag (false, 0);
_editor->commit_reversible_command ();
} else {
/* add a new control point on the line */
AutomationTimeAxisView* atv;
_line->end_drag (false, 0);
if ((atv = dynamic_cast<AutomationTimeAxisView*>(_editor->clicked_axisview)) != 0) {
framepos_t where = _editor->window_event_sample (event, 0, 0);
atv->add_automation_event (event, where, event->button.y, false);
}
}
_editor->commit_reversible_command ();
}
void
@ -5525,8 +5547,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
double const p = j->line->time_converter().from (i->start - j->line->time_converter().origin_b ());
double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
the_list->editor_add (p, value (the_list, p));
the_list->editor_add (q, value (the_list, q));
the_list->editor_add (p, value (the_list, p), false);
the_list->editor_add (q, value (the_list, q), false);
}
/* same thing for the end */
@ -5551,8 +5573,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
double const p = j->line->time_converter().from (b - j->line->time_converter().origin_b ());
double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
the_list->editor_add (p, value (the_list, p));
the_list->editor_add (q, value (the_list, q));
the_list->editor_add (p, value (the_list, p), false);
the_list->editor_add (q, value (the_list, q), false);
}
}
@ -5589,19 +5611,22 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
if (_nothing_to_drag) {
return;
}
for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
i->line->start_drag_multiple (i->points, y_fraction (i->line, current_pointer_y()), i->state);
}
}
void
AutomationRangeDrag::motion (GdkEvent*, bool /*first_move*/)
AutomationRangeDrag::motion (GdkEvent*, bool first_move)
{
if (_nothing_to_drag) {
return;
}
if (first_move) {
_editor->begin_reversible_command (_("automation range move"));
for (list<Line>::iterator i = _lines.begin(); i != _lines.end(); ++i) {
i->line->start_drag_multiple (i->points, y_fraction (i->line, current_pointer_y()), i->state);
}
}
for (list<Line>::iterator l = _lines.begin(); l != _lines.end(); ++l) {
float const f = y_fraction (l->line, current_pointer_y());
/* we are ignoring x position for this drag, so we can just pass in anything */
@ -5612,9 +5637,9 @@ AutomationRangeDrag::motion (GdkEvent*, bool /*first_move*/)
}
void
AutomationRangeDrag::finished (GdkEvent* event, bool)
AutomationRangeDrag::finished (GdkEvent* event, bool motion_occurred)
{
if (_nothing_to_drag) {
if (_nothing_to_drag || !motion_occurred) {
return;
}

View file

@ -877,6 +877,8 @@ private:
double _fixed_grab_x;
double _fixed_grab_y;
double _cumulative_y_drag;
uint32_t _before;
uint32_t _after;
};
/** Transient feature line drags*/

View file

@ -446,7 +446,8 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
if (((mouse_mode != MouseObject) &&
(mouse_mode != MouseAudition || item_type != RegionItem) &&
(mouse_mode != MouseTimeFX || item_type != RegionItem) &&
(mouse_mode != MouseDraw)) ||
(mouse_mode != MouseDraw) &&
(mouse_mode != MouseContent || item_type == RegionItem)) ||
((event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE) || event->button.button > 3)) {
return;
}
@ -512,7 +513,8 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp
break;
case ControlPointItem:
set_selected_track_as_side_effect (op);
/* for object/track exclusivity, we don't call set_selected_track_as_side_effect (op); */
if (eff_mouse_mode != MouseRange) {
_mouse_changed_selection |= set_selected_control_point_from_click (press, op);
}
@ -761,11 +763,21 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
}
return true;
case GainLineItem:
_drags->set (new LineDrag (this, item), event);
return true;
break;
case ControlPointItem:
_drags->set (new ControlPointDrag (this, item), event);
return true;
break;
case AutomationLineItem:
_drags->set (new LineDrag (this, item), event);
return true;
break;
case StreamItem:
//in the past, we created a new midi region here, but perhaps that is best left to the Draw mode
break;
@ -2200,7 +2212,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, framepos_t pos)
// playlist is frozen, so we have to update manually XXX this is disgusting
playlist->RegionAdded (new_region); /* EMIT SIGNAL */
//playlist->RegionAdded (new_region); /* EMIT SIGNAL */
}
gint
@ -2262,8 +2274,6 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView*
}
_drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), true, false));
begin_reversible_command (Operations::drag_region_brush);
}
/** Start a grab where a time range is selected, track(s) are selected, and the
@ -2303,7 +2313,6 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
/* A selection grab currently creates two undo/redo operations, one for
creating the new region and another for moving it.
*/
begin_reversible_command (Operations::selection_grab);
boost::shared_ptr<Playlist> playlist = clicked_axisview->playlist();
@ -2316,6 +2325,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event)
if (latest_regionviews.empty()) {
/* something went wrong */
abort_reversible_command ();
return;
}

File diff suppressed because it is too large Load diff

View file

@ -326,19 +326,23 @@ Editor::set_selected_control_point_from_click (bool press, Selection::Operation
if (!clicked_control_point) {
return false;
}
bool ret = false;
switch (op) {
case Selection::Set:
if (press) {
selection->set (clicked_control_point);
ret = true;
}
break;
case Selection::Add:
if (press) {
selection->add (clicked_control_point);
ret = true;
}
break;
case Selection::Toggle:
/* This is a bit of a hack; if we Primary-Click-Drag a control
point (for push drag) we want the point we clicked on to be
selected, otherwise we end up confusingly dragging an
@ -353,9 +357,11 @@ Editor::set_selected_control_point_from_click (bool press, Selection::Operation
*/
selection->toggle (clicked_control_point);
_control_point_toggled_on_press = true;
ret = true;
} else if (!press && !_control_point_toggled_on_press) {
/* This is the release, and the point wasn't toggled on the press, so do it now */
selection->toggle (clicked_control_point);
ret = true;
} else {
/* Reset our flag */
_control_point_toggled_on_press = false;
@ -366,7 +372,7 @@ Editor::set_selected_control_point_from_click (bool press, Selection::Operation
break;
}
return true;
return ret;
}
void

View file

@ -133,6 +133,8 @@ Editor::pitch_shift (RegionSelection& regions, float fraction)
if (ret == 0) {
commit_reversible_command ();
} else {
abort_reversible_command ();
}
return ret;

View file

@ -1509,8 +1509,9 @@ boost::shared_ptr<MidiRegion>
MidiTimeAxisView::add_region (framepos_t pos, framecnt_t length, bool commit)
{
Editor* real_editor = dynamic_cast<Editor*> (&_editor);
real_editor->begin_reversible_command (Operations::create_region);
if (commit) {
real_editor->begin_reversible_command (Operations::create_region);
}
playlist()->clear_changes ();
real_editor->snap_to (pos, RoundNearest);

View file

@ -270,33 +270,41 @@ RegionEditor::connect_editor_events ()
void
RegionEditor::position_clock_changed ()
{
PublicEditor::instance().begin_reversible_command (_("change region start position"));
bool in_command = false;
boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) {
PublicEditor::instance().begin_reversible_command (_("change region start position"));
in_command = true;
_region->clear_changes ();
_region->set_position (position_clock.current_time());
_session->add_command(new StatefulDiffCommand (_region));
}
PublicEditor::instance().commit_reversible_command ();
if (in_command) {
PublicEditor::instance().commit_reversible_command ();
}
}
void
RegionEditor::end_clock_changed ()
{
PublicEditor::instance().begin_reversible_command (_("change region end position"));
bool in_command = false;
boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) {
PublicEditor::instance().begin_reversible_command (_("change region end position"));
in_command = true;
_region->clear_changes ();
_region->trim_end (end_clock.current_time());
_session->add_command(new StatefulDiffCommand (_region));
}
PublicEditor::instance().commit_reversible_command ();
if (in_command) {
PublicEditor::instance().commit_reversible_command ();
}
end_clock.set (_region->position() + _region->length() - 1, true);
}
@ -305,18 +313,21 @@ void
RegionEditor::length_clock_changed ()
{
framecnt_t frames = length_clock.current_time();
PublicEditor::instance().begin_reversible_command (_("change region length"));
bool in_command = false;
boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) {
_region->clear_changes ();
PublicEditor::instance().begin_reversible_command (_("change region length"));
in_command = true;
_region->clear_changes ();
_region->trim_end (_region->position() + frames - 1);
_session->add_command(new StatefulDiffCommand (_region));
}
PublicEditor::instance().commit_reversible_command ();
if (in_command) {
PublicEditor::instance().commit_reversible_command ();
}
length_clock.set (_region->length());
}

View file

@ -59,6 +59,7 @@
#include "ardour_ui.h"
#include "ardour_button.h"
#include "audio_streamview.h"
#include "debug.h"
#include "global_signals.h"
#include "route_time_axis.h"
@ -1342,6 +1343,10 @@ RouteTimeAxisView::set_selected_points (PointSelection& points)
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
(*i)->set_selected_points (points);
}
AudioStreamView* asv = dynamic_cast<AudioStreamView*>(_view);
if (asv) {
asv->set_selected_points (points);
}
}
void

View file

@ -101,6 +101,7 @@ protected:
ARDOUR::Session& _session;
const ParameterDescriptor _desc;
XMLNode* _before; //used for undo of touch start/stop pairs.
};

View file

@ -19,12 +19,15 @@
*/
#include <iostream>
#include "ardour/automation_control.h"
#include "ardour/automation_watch.h"
#include "ardour/event_type_map.h"
#include "ardour/session.h"
#include "pbd/memento_command.h"
#include "i18n.h"
using namespace std;
using namespace ARDOUR;
using namespace PBD;
@ -85,6 +88,8 @@ AutomationControl::set_automation_state (AutoState as)
}
if (as == Write) {
/* get state for undo */
_before = &alist ()->get_state ();
AutomationWatch::instance().add_automation_watch (shared_from_this());
} else if (as == Touch) {
if (!touching()) {
@ -113,9 +118,16 @@ AutomationControl::set_automation_style (AutoStyle as)
void
AutomationControl::start_touch(double when)
{
if (!_list) return;
if (!_list) {
return;
}
if (!touching()) {
if (alist()->automation_state() == Touch) {
/* subtle. aligns the user value with the playback */
set_value (get_value ());
_before = &alist ()->get_state ();
alist()->start_touch (when);
if (!_desc.toggled) {
AutomationWatch::instance().add_automation_watch (shared_from_this());
@ -131,11 +143,22 @@ AutomationControl::stop_touch(bool mark, double when)
if (!_list) return;
if (touching()) {
set_touching (false);
if (alist()->automation_state() == Write) {
_session.begin_reversible_command (string_compose (_("write %1 automation"), name ()));
_session.add_command (new MementoCommand<AutomationList> (*alist ().get (), _before, &alist ()->get_state ()));
_session.commit_reversible_command ();
}
if (alist()->automation_state() == Touch) {
alist()->stop_touch (mark, when);
if (!_desc.toggled) {
AutomationWatch::instance().remove_automation_watch (shared_from_this());
}
_session.begin_reversible_command (string_compose (_("touch %1 automation"), name ()));
_session.add_command (new MementoCommand<AutomationList> (*alist ().get (), _before, &alist ()->get_state ()));
_session.commit_reversible_command ();
}
}
}

View file

@ -276,7 +276,11 @@ AutomationList::state (bool full)
if (_state != Write) {
root->add_property ("state", auto_state_to_string (_state));
} else {
root->add_property ("state", auto_state_to_string (Off));
if (_events.empty ()) {
root->add_property ("state", auto_state_to_string (Off));
} else {
root->add_property ("state", auto_state_to_string (Touch));
}
}
} else {
/* never save anything but Off for automation state to a template */

View file

@ -128,7 +128,7 @@ AutomationWatch::timer ()
(*aw)->list()->add (time, (*aw)->user_double(), true);
}
}
} else { //transport stopped or reversed. stop the automation pass and start a new one (for bonus points, someday store the previous pass in an undo record)
} else if (time != _last_time) { //transport stopped or reversed. stop the automation pass and start a new one (for bonus points, someday store the previous pass in an undo record)
for (AutomationWatches::iterator aw = automation_watches.begin(); aw != automation_watches.end(); ++aw) {
DEBUG_TRACE (DEBUG::Automation, string_compose ("%1: transport in rewind, speed %2, in write pass ? %3 writing ? %4\n",
(*aw)->name(), _session->transport_speed(), _session->transport_rolling(),

View file

@ -124,8 +124,8 @@ public:
void slide (iterator before, double distance);
void shift (double before, double distance);
virtual void add (double when, double value, bool with_guards=true, bool with_default=true);
virtual void editor_add (double when, double value);
virtual void add (double when, double value, bool with_guards=true, bool with_initial=true);
virtual void editor_add (double when, double value, bool with_guard);
void fast_simple_add (double when, double value);

View file

@ -399,7 +399,7 @@ ControlList::add_guard_point (double when)
most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
double eval_value = unlocked_eval (insert_position);
if (most_recent_insert_iterator == _events.end()) {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at end, adding eval-value there %2\n", this, eval_value));
@ -407,7 +407,7 @@ ControlList::add_guard_point (double when)
/* leave insert iterator at the end */
} else if ((*most_recent_insert_iterator)->when == when) {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at existing point, setting eval-value there %2\n", this, eval_value));
/* most_recent_insert_iterator points to a control event
@ -415,15 +415,15 @@ ControlList::add_guard_point (double when)
nothing to do.
... except ...
advance most_recent_insert_iterator so that the "real"
insert occurs in the right place, since it
points to the control event just inserted.
*/
++most_recent_insert_iterator;
} else {
/* insert a new control event at the right spot
*/
@ -431,7 +431,7 @@ ControlList::add_guard_point (double when)
this, eval_value, (*most_recent_insert_iterator)->when));
most_recent_insert_iterator = _events.insert (most_recent_insert_iterator, new ControlEvent (when, eval_value));
/* advance most_recent_insert_iterator so that the "real"
* insert occurs in the right place, since it
* points to the control event just inserted.
@ -452,7 +452,7 @@ ControlList::in_write_pass () const
}
void
ControlList::editor_add (double when, double value)
ControlList::editor_add (double when, double value, bool with_guard)
{
/* this is for making changes from a graphical line editor
*/
@ -464,11 +464,19 @@ ControlList::editor_add (double when, double value)
*/
if (when >= 1) {
_events.insert (_events.end(), new ControlEvent (0, _default_value));
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added default value %2 at zero\n", this, _default_value));
_events.insert (_events.end(), new ControlEvent (0, value));
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added value %2 at zero\n", this, value));
}
}
insert_position = when;
if (with_guard) {
if (when > 64) {
add_guard_point (when - 64);
}
maybe_add_insert_guard (when);
}
ControlEvent cp (when, 0.0f);
iterator i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
DEBUG_TRACE (DEBUG::ControlList, string_compose ("editor_add: actually add when= %1 value= %2\n", when, value));
@ -491,9 +499,9 @@ ControlList::maybe_add_insert_guard (double when)
new control point so that our insert will happen correctly. */
most_recent_insert_iterator = _events.insert (
most_recent_insert_iterator,
new ControlEvent (when + 1, (*most_recent_insert_iterator)->value));
new ControlEvent (when + 64, (*most_recent_insert_iterator)->value));
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added insert guard point @ %2 = %3\n",
this, when+1,
this, when + 64,
(*most_recent_insert_iterator)->value));
}
}
@ -546,7 +554,7 @@ ControlList::erase_from_iterator_to (iterator iter, double when)
}
void
ControlList::add (double when, double value, bool with_guards, bool with_default)
ControlList::add (double when, double value, bool with_guards, bool with_initial)
{
/* this is for making changes from some kind of user interface or
control surface (GUI, MIDI, OSC etc)
@ -561,12 +569,12 @@ ControlList::add (double when, double value, bool with_guards, bool with_default
ControlEvent cp (when, 0.0f);
iterator insertion_point;
if (_events.empty() && with_default) {
if (_events.empty() && with_initial) {
/* empty: add an "anchor" point if the point we're adding past time 0 */
if (when >= 1) {
_events.insert (_events.end(), new ControlEvent (0, _default_value));
_events.insert (_events.end(), new ControlEvent (0, value));
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added default value %2 at zero\n", this, _default_value));
}
}
@ -628,10 +636,10 @@ ControlList::add (double when, double value, bool with_guards, bool with_default
if ((*most_recent_insert_iterator)->value != value) {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 reset existing point to new value %2\n", this, value));
/* only one point allowed per time point, so just
* reset the value here.
/* only one point allowed per time point, so add a guard point
* before it if needed then reset the value of the point.
*/
(*most_recent_insert_iterator)->value = value;
/* if we modified the final value, then its as
@ -649,10 +657,35 @@ ControlList::add (double when, double value, bool with_guards, bool with_default
} else {
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert new point at %2 at iterator at %3\n", this, when, (*most_recent_insert_iterator)->when));
const bool done = maybe_insert_straight_line (when, value);
bool done = false;
/* check for possible straight line here until maybe_insert_straight_line () handles the insert iterator properly*/
if (most_recent_insert_iterator != _events.begin ()) {
bool have_point2 = false;
--most_recent_insert_iterator;
const bool have_point1 = (*most_recent_insert_iterator)->value == value;
if (most_recent_insert_iterator != _events.begin ()) {
--most_recent_insert_iterator;
have_point2 = (*most_recent_insert_iterator)->value == value;
++most_recent_insert_iterator;
}
if (have_point1 && have_point2) {
(*most_recent_insert_iterator)->when = when;
done = true;
} else {
++most_recent_insert_iterator;
}
}
//done = maybe_insert_straight_line (when, value) || done;
/* if the transport is stopped, add guard points (?) */
if (!done && !_in_write_pass && when > 64) {
add_guard_point (when - 64);
maybe_add_insert_guard (when);
}
if (with_guards) {
maybe_add_insert_guard(when);
maybe_add_insert_guard (when);
}
if (!done) {

View file

@ -58,6 +58,7 @@ class LIBGTKMM2EXT_API PixFader : public CairoWidget
void on_size_allocate (Gtk::Allocation& alloc);
void render (cairo_t *, cairo_rectangle_t*);
bool on_grab_broken_event (GdkEventGrabBroken*);
bool on_button_press_event (GdkEventButton*);
bool on_button_release_event (GdkEventButton*);
bool on_motion_notify_event (GdkEventMotion*);

View file

@ -71,7 +71,7 @@ PixFader::PixFader (Gtk::Adjustment& adj, int orientation, int fader_length, int
_adjustment.signal_value_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
_adjustment.signal_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
signal_grab_broken_event ().connect (mem_fun (*this, &PixFader::on_grab_broken_event));
if (_orien == VERT) {
CairoWidget::set_size_request(_girth, _span);
} else {
@ -365,6 +365,18 @@ PixFader::on_size_allocate (Gtk::Allocation& alloc)
update_unity_position ();
}
bool
PixFader::on_grab_broken_event (GdkEventGrabBroken* ev)
{
if (_dragging) {
remove_modal_grab();
_dragging = false;
gdk_pointer_ungrab (GDK_CURRENT_TIME);
StopGesture ();
}
return (_tweaks & NoButtonForward) ? true : false;
}
bool
PixFader::on_button_press_event (GdkEventButton* ev)
{