*pcy = y;
}
- /* note that pixel_to_sample() never returns less than zero, so even if the pixel
+ /* note that pixel_to_sample_from_event() never returns less than zero, so even if the pixel
position is negative (as can be the case with motion events in particular),
the frame location is always positive.
*/
- return pixel_to_sample (x);
+ return pixel_to_sample_from_event (x);
}
Gdk::Cursor*
to cut notes or regions.
*/
- MouseMode eff_mouse_mode = effective_mouse_mode ();
+ MouseMode eff_mouse_mode = mouse_mode;
if (get_smart_mode() && eff_mouse_mode == MouseRange && event->button.button == 3 && item_type == RegionItem) {
/* context clicks are always about object properties, even if
eff_mouse_mode = MouseObject;
}
- if (((eff_mouse_mode != MouseObject) &&
- (eff_mouse_mode != MouseAudition || item_type != RegionItem) &&
- (eff_mouse_mode != MouseTimeFX || item_type != RegionItem) &&
- (eff_mouse_mode != MouseGain) &&
- (eff_mouse_mode != MouseDraw)) ||
+ if (((mouse_mode != MouseObject) &&
+ (mouse_mode != MouseAudition || item_type != RegionItem) &&
+ (mouse_mode != MouseTimeFX || item_type != RegionItem) &&
+ (mouse_mode != MouseGain) &&
+ (mouse_mode != MouseDraw)) ||
((event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE) || event->button.button > 3) ||
- (internal_editing() && eff_mouse_mode != MouseTimeFX)) {
+ (internal_editing() && mouse_mode != MouseTimeFX)) {
return;
}
case RegionViewName:
case LeftFrameHandle:
case RightFrameHandle:
- if ( mouse_mode != MouseRange ) {
+ if (eff_mouse_mode != MouseRange) {
set_selected_regionview_from_click (press, op);
} else if (event->type == GDK_BUTTON_PRESS) {
set_selected_track_as_side_effect (op);
case FadeOutItem:
case StartCrossFadeItem:
case EndCrossFadeItem:
- if ( mouse_mode != MouseRange ) {
+ if (eff_mouse_mode != MouseRange) {
+ cerr << "Should be setting selected regionview\n";
set_selected_regionview_from_click (press, op);
} else if (event->type == GDK_BUTTON_PRESS) {
set_selected_track_as_side_effect (op);
case ControlPointItem:
set_selected_track_as_side_effect (op);
- if ( mouse_mode != MouseRange ) {
+ if (eff_mouse_mode != MouseRange) {
set_selected_control_point_from_click (press, op);
}
break;
case MouseDraw:
switch (item_type) {
case NoteItem:
+ /* Existing note: allow trimming/motion */
if (internal_editing()) {
/* trim notes if we're in internal edit mode and near the ends of the note */
NoteBase* cn = reinterpret_cast<NoteBase*>(item->get_data ("notebase"));
assert (cn);
- if (cn && cn->big_enough_to_trim() && cn->mouse_near_ends()) {
+ if (cn->big_enough_to_trim() && cn->mouse_near_ends()) {
_drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
} else {
_drags->set (new NoteDrag (this, item), event);
}
return true;
- }
+ }
break;
case StreamItem:
if (internal_editing()) {
case MouseObject:
switch (item_type) {
case NoteItem:
+ /* Existing note: allow trimming/motion */
if (internal_editing()) {
NoteBase* cn = reinterpret_cast<NoteBase*> (item->get_data ("notebase"));
assert (cn);
- if (cn->mouse_near_ends()) {
+ if (cn->big_enough_to_trim() && cn->mouse_near_ends()) {
_drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
} else {
_drags->set (new NoteDrag (this, item), event);
break;
case MouseTimeFX:
- if (internal_editing() && item_type == NoteItem) {
+ if (internal_editing() && item_type == NoteItem ) {
/* drag notes if we're in internal edit mode */
- _drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
+ NoteBase* cn = reinterpret_cast<NoteBase*>(item->get_data ("notebase"));
+ assert (cn);
+ if (cn->big_enough_to_trim()) {
+ _drags->set (new NoteResizeDrag (this, item), event, current_canvas_cursor);
+ }
return true;
} else if (clicked_regionview) {
/* do time-FX */
}
pre_press_cursor = current_canvas_cursor;
-
+
_track_canvas->grab_focus();
if (_session && _session->actively_recording()) {
}
break;
+ case RegionItem:
+ switch (effective_mouse_mode()) {
+ case MouseRange:
+ set_canvas_cursor (_cursors->selector);
+ break;
+ default:
+ set_canvas_cursor (which_grabber_cursor());
+ break;
+ }
+ break;
+
case StartSelectionTrimItem:
if (is_drawable()) {
set_canvas_cursor (_cursors->left_side_trim);
}
break;
+
case RegionViewName:
/* when the name is not an active item, the entire name highlight is for trimming */
line->set_outline_color (0xFF0000FF);
}
break;
-
+
case SelectionItem:
if ( get_smart_mode() ) {
set_canvas_cursor ();
return;
}
- assert (rv);
-
ArdourCanvas::Group* g = rv->get_canvas_group ();
ArdourCanvas::Group* p = g->parent ();
assert (item_bbox);
ArdourCanvas::Rect parent_bbox = g->item_to_parent (item_bbox.get ());
- /* Halfway across the region */
- double const h = (parent_bbox.x0 + parent_bbox.x1) / 2;
+ /* First or last 10% of region is used for trimming, if the whole
+ region is wider than 20 pixels at the current zoom level.
+ */
- Trimmable::CanTrim ct = rv->region()->can_trim ();
- if (x <= h) {
- if (ct & Trimmable::FrontTrimEarlier) {
- set_canvas_cursor (_cursors->left_side_trim);
- } else {
- set_canvas_cursor (_cursors->left_side_trim_right_only);
- }
- } else {
- if (ct & Trimmable::EndTrimLater) {
- set_canvas_cursor (_cursors->right_side_trim);
- } else {
- set_canvas_cursor (_cursors->right_side_trim_left_only);
+ double const w = parent_bbox.width();
+
+ if (w > 20.0 && x >= parent_bbox.x0 && x < parent_bbox.x1) {
+
+ Trimmable::CanTrim ct = rv->region()->can_trim ();
+
+ if (((x - parent_bbox.x0) / w) < 0.10) {
+ if (ct & Trimmable::FrontTrimEarlier) {
+ set_canvas_cursor (_cursors->left_side_trim, true);
+ } else {
+ set_canvas_cursor (_cursors->left_side_trim_right_only, true);
+ }
+ } else if (((parent_bbox.x1 - x) / w) < 0.10) {
+ if (ct & Trimmable::EndTrimLater) {
+ set_canvas_cursor (_cursors->right_side_trim, true);
+ } else {
+ set_canvas_cursor (_cursors->right_side_trim_left_only, true);
+ }
}
}
}