bool
Editor::mouse_frame (framepos_t& where, bool& in_track_canvas) const
{
+ /* gdk_window_get_pointer() has X11's XQueryPointer semantics in that it only
+ pays attentions to subwindows. this means that menu windows are ignored, and
+ if the pointer is in a menu, the return window from the call will be the
+ the regular subwindow *under* the menu.
+
+ this matters quite a lot if the pointer is moving around in a menu that overlaps
+ the track canvas because we will believe that we are within the track canvas
+ when we are not. therefore, we track enter/leave events for the track canvas
+ and allow that to override the result of gdk_window_get_pointer().
+ */
+
+ if (!within_track_canvas) {
+ return false;
+ }
+
int x, y;
double wx, wy;
Gdk::ModifierType mask;
instant_save ();
if (!internal_editing()) {
- if (mouse_mode != MouseRange && _join_object_range_state == JOIN_OBJECT_RANGE_NONE) {
+ if (mouse_mode != MouseRange && mouse_mode != MouseGain && _join_object_range_state == JOIN_OBJECT_RANGE_NONE) {
- /* in all modes except range and joined object/range, hide the range selection,
+ /* in all modes except range, gain and joined object/range, hide the range selection,
show the object (region) selection.
*/
}
break;
-
case FadeInHandleItem:
case FadeInItem:
case FadeOutHandleItem:
case FadeOutItem:
+ case StartCrossFadeItem:
+ case EndCrossFadeItem:
if (doing_object_stuff() || (mouse_mode != MouseRange && mouse_mode != MouseObject)) {
set_selected_regionview_from_click (press, op);
} else if (event->type == GDK_BUTTON_PRESS) {
case ControlPointItem:
set_selected_track_as_side_effect (op);
if (doing_object_stuff() || (mouse_mode != MouseRange && mouse_mode != MouseObject)) {
- set_selected_control_point_from_click (op, false);
+ set_selected_control_point_from_click (press, op);
}
break;
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
if (smart_mode_action->get_active() && atv) {
/* smart "join" mode: drag automation */
- _drags->set (new AutomationRangeDrag (this, atv->base_item(), selection->time), event, _cursors->up_down);
+ _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
} else {
/* this was debated, but decided the more common action was to
make a new selection */
default:
break;
}
+ break;
case MouseObject:
switch (item_type) {
return true;
}
+ case StartCrossFadeItem:
+ _drags->set (new CrossfadeEdgeDrag (this, reinterpret_cast<AudioRegionView*>(item->get_data("regionview")), item, true), event, 0);
+ break;
+
+ case EndCrossFadeItem:
+ _drags->set (new CrossfadeEdgeDrag (this, reinterpret_cast<AudioRegionView*>(item->get_data("regionview")), item, false), event, 0);
+ break;
+
case FeatureLineItem:
{
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
/* if we're over an automation track, start a drag of its data */
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
if (atv) {
- _drags->set (new AutomationRangeDrag (this, atv->base_item(), selection->time), event, _cursors->up_down);
+ _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
}
/* if we're over a track and a region, and in the `object' part of a region,
case MouseGain:
switch (item_type) {
- case RegionItem:
- /* start a grab so that if we finish after moving
- we can tell what happened.
- */
- _drags->set (new RegionGainDrag (this, item), event, current_canvas_cursor);
- break;
-
case GainLineItem:
_drags->set (new LineDrag (this, item), event);
return true;
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);
+ _drags->start_grab (event);
+ }
+ return true;
break;
}
- return true;
- break;
-
- switch (item_type) {
- case ControlPointItem:
- _drags->set (new ControlPointDrag (this, item), event);
- break;
case AutomationLineItem:
_drags->set (new LineDrag (this, item), event);
break;
-
- case RegionItem:
- // XXX need automation mode to identify which
- // line to use
- // start_line_grab_from_regionview (item, event);
- break;
-
+
default:
break;
}
break;
case RegionItem:
- if (!dynamic_cast<MidiRegionView*> (clicked_regionview)) {
+ if (!dynamic_cast<MidiRegionView*> (clicked_regionview) && !dynamic_cast<AutomationRegionView*> (clicked_regionview)) {
leave_internal_edit_mode = true;
}
break;
popup_fade_context_menu (1, event->button.time, item, item_type);
break;
+ case StartCrossFadeItem:
+ popup_xfade_in_context_menu (1, event->button.time, item, item_type);
+ break;
+
+ case EndCrossFadeItem:
+ popup_xfade_out_context_menu (1, event->button.time, item, item_type);
+ break;
+
case StreamItem:
popup_track_context_menu (1, event->button.time, item_type, false);
break;
case SelectionItem:
popup_track_context_menu (1, event->button.time, item_type, true);
break;
-
+
case AutomationTrackItem:
popup_track_context_menu (1, event->button.time, item_type, false);
break;
points when doing this.
*/
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (clicked_regionview);
- if (were_dragging && arv) {
+ if (!were_dragging && arv) {
arv->add_gain_point_event (item, event);
}
return true;
void
Editor::set_internal_edit (bool yn)
{
+ if (_internal_editing == yn) {
+ return;
+ }
+
_internal_editing = yn;
if (yn) {
pre_internal_mouse_mode = mouse_mode;
+ pre_internal_snap_type = _snap_type;
+ pre_internal_snap_mode = _snap_mode;
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(*i)->enter_internal_edit_mode ();
}
+ set_snap_to (internal_snap_type);
+ set_snap_mode (internal_snap_mode);
+
} else {
+
+ internal_snap_mode = _snap_mode;
+ internal_snap_type = _snap_type;
+
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(*i)->leave_internal_edit_mode ();
}
/* we were drawing .. flip back to something sensible */
set_mouse_mode (pre_internal_mouse_mode);
}
+
+ set_snap_to (pre_internal_snap_type);
+ set_snap_mode (pre_internal_snap_mode);
}
set_canvas_cursor ();