Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
assert (tact);
- if (tact->get_active()) {
- m = MouseObject; //Smart mode turned to ON, force editing to Object mode
- }
-
set_mouse_mode(m, true); //call this so the button styles can get updated
}
void
Editor::update_time_selection_display ()
{
- if (smart_mode_action->get_active()) {
- /* not sure what to do here */
- if (mouse_mode == MouseObject) {
- } else {
- }
- } else {
- switch (mouse_mode) {
- case MouseRange:
- selection->clear_objects ();
- selection->ClearMidiNoteSelection(); //signal
- break;
- case MouseObject:
- selection->clear_objects ();
- selection->clear_time ();
- selection->clear_tracks ();
- selection->ClearMidiNoteSelection(); //signal
- break;
- case MouseContent:
- case MouseDraw:
- //if we go into internal editing, clear everything in the outside world
- selection->clear_objects ();
- selection->clear_time ();
- selection->clear_tracks ();
- break;
- default:
- //clear everything
- selection->clear_objects ();
- selection->clear_time ();
- selection->clear_tracks ();
- break;
- }
+ switch (mouse_mode) {
+ case MouseRange:
+ selection->clear_objects ();
+ selection->ClearMidiNoteSelection (); /* EMIT SIGNAL */
+ break;
+ case MouseObject:
+ selection->clear_time ();
+ selection->clear_tracks ();
+ selection->ClearMidiNoteSelection (); /* EMIT SIGNAL */
+ break;
+ case MouseDraw:
+ /* Clear regions, but not time or tracks, since that
+ would destroy the range selection rectangle, which we need to stick
+ around for AutomationRangeDrag. */
+ selection->clear_regions ();
+ selection->clear_playlists ();
+ break;
+ case MouseContent:
+ /* This handles internal edit.
+ Clear everything except points and notes.
+ */
+ selection->clear_regions();
+ selection->clear_lines();
+ selection->clear_playlists ();
+
+ selection->clear_time ();
+ selection->clear_tracks ();
+ break;
+
+ case MouseTimeFX:
+ /* We probably want to keep region selection */
+ selection->clear_points ();
+ selection->clear_lines();
+ selection->clear_playlists ();
+
+ selection->clear_time ();
+ selection->clear_tracks ();
+ break;
+
+ case MouseAudition:
+ /*Don't lose lines or points if no action in this mode */
+ selection->clear_regions ();
+ selection->clear_playlists ();
+ selection->clear_time ();
+ selection->clear_tracks ();
+ break;
+
+ default:
+ /*Clear everything */
+ selection->clear_objects();
+ selection->clear_time ();
+ selection->clear_tracks ();
+ break;
}
}
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;
}
Selection::Operation op = ArdourKeyboard::selection_type (event->button.state);
bool press = (event->type == GDK_BUTTON_PRESS);
+ if (press) {
+ _mouse_changed_selection = false;
+ }
+
switch (item_type) {
case RegionItem:
if (press) {
if (eff_mouse_mode != MouseRange) {
- set_selected_regionview_from_click (press, op);
+ _mouse_changed_selection = set_selected_regionview_from_click (press, op);
} else {
/* don't change the selection unless the
clicked track is not currently selected. if
}
} else {
if (eff_mouse_mode != MouseRange) {
- set_selected_regionview_from_click (press, op);
+ _mouse_changed_selection |= set_selected_regionview_from_click (press, op);
}
}
break;
case StartCrossFadeItem:
case EndCrossFadeItem:
if (get_smart_mode() || eff_mouse_mode != MouseRange) {
- set_selected_regionview_from_click (press, op);
+ _mouse_changed_selection |= set_selected_regionview_from_click (press, op);
} else if (event->type == GDK_BUTTON_PRESS) {
set_selected_track_as_side_effect (op);
}
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) {
- set_selected_control_point_from_click (press, op);
+ _mouse_changed_selection |= set_selected_control_point_from_click (press, op);
}
break;
if (event->button.button == 3) {
selection->clear_tracks ();
set_selected_track_as_side_effect (op);
+
+ /* We won't get a release.*/
+ begin_reversible_selection_op (X_("Button 3 Menu Select"));
+ commit_reversible_selection_op ();
}
break;
default:
break;
}
+
+ if ((!press) && _mouse_changed_selection) {
+ begin_reversible_selection_op (X_("Button Selection"));
+ commit_reversible_selection_op ();
+ _mouse_changed_selection = false;
+ }
}
bool
}
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:
- if (dynamic_cast<MidiTimeAxisView*> (clicked_axisview)) {
- _drags->set (new RegionCreateDrag (this, item, clicked_axisview), event);
- return true;
- }
+ //in the past, we created a new midi region here, but perhaps that is best left to the Draw mode
break;
case AutomationTrackItem:
/* rubberband drag to select automation points */
_drags->set (new EditorRubberbandSelectDrag (this, item), event);
+ return true;
+ break;
+
+ case RegionItem:
+ if (dynamic_cast<AutomationRegionView*>(clicked_regionview)) {
+ /* rubberband drag to select automation points */
+ _drags->set (new EditorRubberbandSelectDrag (this, item), event);
+ return true;
+ }
break;
default:
case SelectionItem:
{
- AudioRegionView* arv = dynamic_cast<AudioRegionView *> (clicked_regionview);
- if (arv) {
- _drags->set (new AutomationRangeDrag (this, arv, selection->time), event, _cursors->up_down);
+ if (dynamic_cast<AudioRegionView*>(clicked_regionview) ||
+ dynamic_cast<AutomationRegionView*>(clicked_regionview)) {
+ _drags->set (new AutomationRangeDrag (this, clicked_regionview, selection->time),
+ event, _cursors->up_down);
} else {
double const y = event->button.y;
- pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
+ pair<TimeAxisView*, int> tvp = trackview_by_y_position (y, false);
if (tvp.first) {
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
if ( atv) {
}
//not rolling, range mode click + join_play_range : locate the PH here
- if ( !_drags->active () && !_session->transport_rolling() && ( effective_mouse_mode() == MouseRange ) && ARDOUR_UI::config()->get_follow_edits() ) {
+ if ( !_drags->active () && _session && !_session->transport_rolling() && ( effective_mouse_mode() == MouseRange ) && ARDOUR_UI::config()->get_follow_edits() ) {
framepos_t where = canvas_event_sample (event);
snap_to(where);
_session->request_locate (where, false);
return true;
}
- /* see if we're finishing a drag */
+ bool were_dragging = false;
- bool were_dragging = false;
- if (_drags->active ()) {
- bool const r = _drags->end_grab (event);
- if (r) {
- /* grab dragged, so do nothing else */
- return true;
- }
+ if (!Keyboard::is_context_menu_event (&event->button)) {
- were_dragging = true;
- }
+ /* see if we're finishing a drag */
+
+ if (_drags->active ()) {
+ bool const r = _drags->end_grab (event);
+ if (r) {
+ /* grab dragged, so do nothing else */
+ return true;
+ }
+
+ were_dragging = true;
+ }
- update_region_layering_order_editor ();
+ update_region_layering_order_editor ();
+ }
/* edit events get handled here */
break;
case TempoMarkerItem: {
- Marker* marker;
+ ArdourMarker* marker;
TempoMarker* tempo_marker;
- if ((marker = reinterpret_cast<Marker *> (item->get_data ("marker"))) == 0) {
+ if ((marker = reinterpret_cast<ArdourMarker *> (item->get_data ("marker"))) == 0) {
fatal << _("programming error: tempo marker canvas item has no marker object pointer!") << endmsg;
abort(); /*NOTREACHED*/
}
}
case MeterMarkerItem: {
- Marker* marker;
+ ArdourMarker* marker;
MeterMarker* meter_marker;
- if ((marker = reinterpret_cast<Marker *> (item->get_data ("marker"))) == 0) {
+ if ((marker = reinterpret_cast<ArdourMarker *> (item->get_data ("marker"))) == 0) {
fatal << _("programming error: tempo marker canvas item has no marker object pointer!") << endmsg;
abort(); /*NOTREACHED*/
}
default:
break;
}
- } else {
+ } else if (_session) {
/* make sure we stop */
_session->request_transport_speed (0.0);
}
}
/* do any (de)selection operations that should occur on button release */
- button_selection (item, event, item_type);
+ button_selection (item, event, item_type);
+
return true;
break;
Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
ControlPoint* cp;
- Marker * marker;
+ ArdourMarker * marker;
double fraction;
bool ret = true;
break;
case MarkerItem:
- if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
+ if ((marker = static_cast<ArdourMarker *> (item->get_data ("marker"))) == 0) {
break;
}
entered_marker = marker;
case SelectionItem:
break;
+ case WaveItem:
+ {
+ if (entered_regionview) {
+ entered_regionview->entered();
+ }
+ }
+ break;
+
default:
break;
}
Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
{
AutomationLine* al;
- Marker *marker;
+ ArdourMarker *marker;
Location *loc;
bool is_start;
bool ret = true;
- _enter_stack.pop_back();
+ if (!_enter_stack.empty()) {
+ _enter_stack.pop_back();
+ }
switch (item_type) {
case ControlPointItem:
break;
case MarkerItem:
- if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
+ if ((marker = static_cast<ArdourMarker *> (item->get_data ("marker"))) == 0) {
break;
}
entered_marker = 0;
}
ControlPointDialog d (p);
- ensure_float (d);
if (d.run () != RESPONSE_ACCEPT) {
return;
EditNoteDialog* d = new EditNoteDialog (mrv, s);
d->show_all ();
- ensure_float (*d);
d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &Editor::note_edit_done), d));
}
void
Editor::hide_marker (ArdourCanvas::Item* item, GdkEvent* /*event*/)
{
- Marker* marker;
+ ArdourMarker* marker;
bool is_start;
- if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
+ if ((marker = static_cast<ArdourMarker *> (item->get_data ("marker"))) == 0) {
fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
abort(); /*NOTREACHED*/
}
// 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
}
_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
/* 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();
if (latest_regionviews.empty()) {
/* something went wrong */
+ abort_reversible_command ();
return;
}
ArdourCanvas::Duple const item_space = entered_regionview->get_canvas_group()->canvas_to_item (ArdourCanvas::Duple (0, y));
double const c = item_space.y / entered_regionview->height();
-
+
_join_object_range_state = c <= 0.5 ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT;
Editor::EnterContext* ctx = get_enter_context(RegionItem);