}
int x, y;
- double wx, wy;
- Gdk::ModifierType mask;
- Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->_track_canvas_viewport->get_bin_window();
- Glib::RefPtr<const Gdk::Window> pointer_window;
+ Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->_track_canvas->get_window();
if (!canvas_window) {
return false;
}
- pointer_window = canvas_window->get_pointer (x, y, mask);
+ Glib::RefPtr<const Gdk::Window> pointer_window = Gdk::Display::get_default()->get_window_at_pointer (x, y);
- if (pointer_window == _track_canvas->get_window()) {
- wx = x;
- wy = y;
- in_track_canvas = true;
- } else {
+ if (!pointer_window) {
+ return false;
+ }
+
+ if (pointer_window != canvas_window && pointer_window != _time_bars_canvas->get_window()) {
in_track_canvas = false;
return false;
}
+ in_track_canvas = true;
+
GdkEvent event;
event.type = GDK_BUTTON_RELEASE;
- event.button.x = wx;
- event.button.y = wy;
+ event.button.x = x;
+ event.button.y = y;
+
+ where = window_event_frame (&event, 0, 0);
- where = event_frame (&event, 0, 0);
return true;
}
framepos_t
-Editor::event_frame (GdkEvent const * event, double* pcx, double* pcy) const
+Editor::window_event_frame (GdkEvent const * event, double* pcx, double* pcy) const
{
- double cx, cy;
+ double x;
+ double y;
- if (pcx == 0) {
- pcx = &cx;
+ if (!gdk_event_get_coords (event, &x, &y)) {
+ return 0;
}
- if (pcy == 0) {
- pcy = &cy;
+
+ /* event coordinates are in window units, so convert to canvas
+ * (i.e. account for scrolling)
+ */
+
+ ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (x, y));
+
+ if (pcx) {
+ *pcx = d.x;
}
- *pcx = 0;
- *pcy = 0;
+ if (pcy) {
+ *pcy = d.y;
+ }
- /* The event coordinates will be canvas coordinates */
+ return pixel_to_sample (d.x);
+}
- switch (event->type) {
- case GDK_BUTTON_RELEASE:
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- *pcx = event->button.x;
- *pcy = event->button.y;
- _trackview_group->canvas_to_item (*pcx, *pcy);
- break;
- case GDK_MOTION_NOTIFY:
- *pcx = event->motion.x;
- *pcy = event->motion.y;
- _trackview_group->canvas_to_item (*pcx, *pcy);
- break;
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY:
- *pcx = event->crossing.x;
- *pcy = event->crossing.y;
- /* XXX: CANVAS */
-// track_canvas->w2c(event->crossing.x, event->crossing.y, *pcx, *pcy);
- break;
- case GDK_KEY_PRESS:
- case GDK_KEY_RELEASE:
- // track_canvas->w2c(event->key.x, event->key.y, *pcx, *pcy);
- break;
- default:
- warning << string_compose (_("Editor::event_frame() used on unhandled event type %1"), event->type) << endmsg;
- break;
+framepos_t
+Editor::canvas_event_frame (GdkEvent const * event, double* pcx, double* pcy) const
+{
+ double x;
+ double y;
+
+ /* event coordinates are already in canvas units */
+
+ if (!gdk_event_get_coords (event, &x, &y)) {
+ cerr << "!NO c COORDS for event type " << event->type << endl;
+ return 0;
}
- /* note that pixel_to_frame() never returns less than zero, so even if the pixel
+ if (pcx) {
+ *pcx = x;
+ }
+
+ if (pcy) {
+ *pcy = y;
+ }
+
+ /* note that pixel_to_sample() 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_frame (*pcx);
+ return pixel_to_sample (x);
}
Gdk::Cursor*
/* up-down cursor as a cue that automation can be dragged up and down when in join object/range mode */
if (!_internal_editing && get_smart_mode() ) {
+
double x, y;
get_pointer_position (x, y);
- vector<ArdourCanvas::Item const *> items;
- _track_canvas->root()->add_items_at_point (ArdourCanvas::Duple (x,y), items);
-
- // CAIROCANVAS: need upper-most item, not all items
- if (!items.empty()) {
- const ArdourCanvas::Item* i = items.front();
- if (i && i->parent() && i->parent()->get_data (X_("timeselection"))) {
- pair<TimeAxisView*, int> tvp = trackview_by_y_position (_last_motion_y + vertical_adjustment.get_value());
- if (dynamic_cast<AutomationTimeAxisView*> (tvp.first)) {
- current_canvas_cursor = _cursors->up_down;
+ if (x >= 0 && y >= 0) {
+
+ vector<ArdourCanvas::Item const *> items;
+
+ _track_canvas->root()->add_items_at_point (ArdourCanvas::Duple (x,y), items);
+
+ // first item will be the upper most
+
+ if (!items.empty()) {
+ const ArdourCanvas::Item* i = items.front();
+
+ if (i && i->parent() && i->parent()->get_data (X_("timeselection"))) {
+ pair<TimeAxisView*, int> tvp = trackview_by_y_position (_last_motion_y);
+ if (dynamic_cast<AutomationTimeAxisView*> (tvp.first)) {
+ current_canvas_cursor = _cursors->up_down;
+ }
}
}
}
switch (item_type) {
case RegionItem:
- if (!get_smart_mode() || (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT)) {
+ if (!get_smart_mode() || (_join_object_range_state != JOIN_OBJECT_RANGE_RANGE)) {
if (press) {
if (mouse_mode != MouseRange) {
set_selected_regionview_from_click (press, op);
switch (item_type) {
case PlayheadCursorItem:
- _drags->set (new CursorDrag (this, item, true), event);
+ _drags->set (new CursorDrag (this, *playhead_cursor, true), event);
return true;
case MarkerItem:
}
}
-#ifdef WITH_VIDEOTIMELINE
case VideoBarItem:
_drags->set (new VideoTimeLineDrag (this, item), event);
return true;
break;
-#endif
case MarkerBarItem:
case TempoBarItem:
case MeterBarItem:
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
- _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), event);
+ _drags->set (new CursorDrag (this, *playhead_cursor, false), event);
}
return true;
break;
case RangeMarkerBarItem:
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
- _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), event);
+ _drags->set (new CursorDrag (this, *playhead_cursor, false), event);
} else {
_drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateRangeMarker), event);
}
case CdMarkerBarItem:
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
- _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), event);
+ _drags->set (new CursorDrag (this, *playhead_cursor, false), event);
} else {
_drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateCDMarker), event);
}
case TransportMarkerBarItem:
if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
- _drags->set (new CursorDrag (this, &playhead_cursor->track_canvas_item (), false), event);
+ _drags->set (new CursorDrag (this, *playhead_cursor, false), event);
} else {
_drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateTransportMarker), event);
}
/* grab selection for moving */
_drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionMove), event);
} else {
- double const y = event->button.y + vertical_adjustment.get_value();
+ double const y = event->button.y;
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
if (tvp.first) {
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
case RegionViewNameHighlight:
if (!clicked_regionview->region()->locked()) {
- RegionSelection s = get_equivalent_regions (selection->regions, Properties::select.property_id);
- _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event);
+ _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
return true;
}
break;
switch (item_type) {
case FadeInHandleItem:
{
- RegionSelection s = get_equivalent_regions (selection->regions, Properties::select.property_id);
- _drags->set (new FadeInDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s), event, _cursors->fade_in);
+ _drags->set (new FadeInDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), selection->regions), event, _cursors->fade_in);
return true;
}
case FadeOutHandleItem:
{
- RegionSelection s = get_equivalent_regions (selection->regions, Properties::select.property_id);
- _drags->set (new FadeOutDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), s), event, _cursors->fade_out);
+ _drags->set (new FadeOutDrag (this, item, reinterpret_cast<RegionView*> (item->get_data("regionview")), selection->regions), event, _cursors->fade_out);
return true;
}
case EndCrossFadeItem:
/* we might allow user to grab inside the fade to trim a region with preserve_fade_anchor. for not this is not fully implemented */
// if (!clicked_regionview->region()->locked()) {
-// RegionSelection s = get_equivalent_regions (selection->regions, Properties::edit.property_id);
-// _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer(), true), event);
+// _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer(), true), event);
// return true;
// }
break;
}
if (internal_editing ()) {
- if (event->type == GDK_2BUTTON_PRESS && event->button.button == 1) {
- Glib::RefPtr<Action> act = ActionManager::get_action (X_("MouseMode"), X_("toggle-internal-edit"));
- act->activate ();
- }
break;
}
case LeftFrameHandle:
case RightFrameHandle:
if (!clicked_regionview->region()->locked()) {
- RegionSelection s = get_equivalent_regions (selection->regions, Properties::select.property_id);
- _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event);
+ _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event);
return true;
}
break;
case RegionViewName:
{
/* rename happens on edit clicks */
- RegionSelection s = get_equivalent_regions (selection->regions, Properties::select.property_id);
- _drags->set (new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, s.by_layer()), event);
+ _drags->set (new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer()), event);
return true;
break;
}
_drags->set (new RegionCreateDrag (this, item, parent), event);
} else {
/* See if there's a region before the click that we can extend, and extend it if so */
- framepos_t const t = event_frame (event);
+ framepos_t const t = canvas_event_frame (event);
boost::shared_ptr<Region> prev = pl->find_next_region (t, End, -1);
if (!prev) {
_drags->set (new RegionCreateDrag (this, item, parent), event);
{
if ( get_smart_mode() ) {
/* we're in "smart" joined mode, and we've clicked on a Selection */
- double const y = event->button.y + vertical_adjustment.get_value();
+ double const y = event->button.y;
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
if (tvp.first) {
/* if we're over an automation track, start a drag of its data */
boost::shared_ptr<Playlist> pl = t->playlist ();
if (pl) {
- boost::shared_ptr<Region> r = pl->top_region_at (event_frame (event));
+ boost::shared_ptr<Region> r = pl->top_region_at (canvas_event_frame (event));
if (r) {
RegionView* rv = rtv->view()->find_view (r);
clicked_selection = select_range (rv->region()->position(),
break;
}
-#ifdef WITH_CMT
- case ImageFrameHandleStartItem:
- imageframe_start_handle_op(item, event) ;
- return(true) ;
- break ;
- case ImageFrameHandleEndItem:
- imageframe_end_handle_op(item, event) ;
- return(true) ;
- break ;
- case MarkerViewHandleStartItem:
- markerview_item_start_handle_op(item, event) ;
- return(true) ;
- break ;
- case MarkerViewHandleEndItem:
- markerview_item_end_handle_op(item, event) ;
- return(true) ;
- break ;
- case MarkerViewItem:
- start_markerview_grab(item, event) ;
- break ;
- case ImageFrameItem:
- start_imageframe_grab(item, event) ;
- break ;
-#endif
-
case MarkerBarItem:
break;
case MouseZoom:
if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
- temporal_zoom_to_frame (false, event_frame (event));
+ temporal_zoom_to_frame (false, canvas_event_frame (event));
} else {
- temporal_zoom_to_frame (true, event_frame(event));
+ temporal_zoom_to_frame (true, canvas_event_frame(event));
}
return true;
break;
bool
Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
+ if (event->type == GDK_2BUTTON_PRESS) {
+ _drags->mark_double_click ();
+ return false;
+ }
+
if (event->type != GDK_BUTTON_PRESS) {
return false;
}
pointer_window = canvas_window->get_pointer (x, y, mask);
if (pointer_window == _track_canvas->get_window()) {
- _track_canvas_viewport->window_to_canvas (x, y, wx, wy);
+ _track_canvas->window_to_canvas (x, y, wx, wy);
}
}
//not rolling, range mode click + join_play_range : locate the PH here
if ( !_drags->active () && !_session->transport_rolling() && ( effective_mouse_mode() == MouseRange ) && Config->get_always_play_range() ) {
- framepos_t where = event_frame (event, 0, 0);
+ framepos_t where = canvas_event_frame (event);
snap_to(where);
_session->request_locate (where, false);
}
bool
Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{
- framepos_t where = event_frame (event, 0, 0);
+ framepos_t where = canvas_event_frame (event);
AutomationTimeAxisView* atv = 0;
if (pre_press_cursor) {
were_dragging = true;
}
- update_region_layering_order_editor ();
+ update_region_layering_order_editor ();
/* edit events get handled here */
edit_control_point (item);
break;
- case NoteItem:
- {
- NoteBase* e = reinterpret_cast<NoteBase*> (item->get_data ("notebase"));
- assert (e);
- edit_notes (e->region_view().selection ());
- break;
- }
-
default:
break;
}
case CdMarkerBarItem:
case TempoBarItem:
case MeterBarItem:
-#ifdef WITH_VIDEOTIMELINE
case VideoBarItem:
-#endif
popup_ruler_menu (where, item_type);
break;
popup_control_point_context_menu (item, event);
break;
-#ifdef WITH_CMT
- case ImageFrameItem:
- popup_imageframe_edit_menu(1, event->button.time, item, true) ;
- break ;
- case ImageFrameTimeAxisItem:
- popup_imageframe_edit_menu(1, event->button.time, item, false) ;
- break ;
- case MarkerViewItem:
- popup_marker_time_axis_edit_menu(1, event->button.time, item, true) ;
- break ;
- case MarkerTimeAxisItem:
- popup_marker_time_axis_edit_menu(1, event->button.time, item, false) ;
- break ;
-#endif
-
default:
break;
}
case MeterBarItem:
if (!_dragging_playhead) {
- mouse_add_new_meter_event (pixel_to_frame (event->button.x));
+ mouse_add_new_meter_event (pixel_to_sample (event->button.x));
}
return true;
break;
if (mouse_mode == MouseGain) {
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
if (line) {
- line->set_outline_color (ARDOUR_UI::config()->canvasvar_EnteredGainLine.get());
+ line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_EnteredGainLine());
}
if (is_drawable()) {
set_canvas_cursor (_cursors->fader);
if (mouse_mode == MouseGain || mouse_mode == MouseObject) {
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
if (line) {
- line->set_outline_color (ARDOUR_UI::config()->canvasvar_EnteredAutomationLine.get());
+ line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_EnteredAutomationLine());
}
if (is_drawable()) {
set_canvas_cursor (_cursors->fader);
break;
case StartSelectionTrimItem:
-#ifdef WITH_CMT
- case ImageFrameHandleStartItem:
- case MarkerViewHandleStartItem:
-#endif
if (is_drawable()) {
set_canvas_cursor (_cursors->left_side_trim);
}
break;
case EndSelectionTrimItem:
-#ifdef WITH_CMT
- case ImageFrameHandleEndItem:
- case MarkerViewHandleEndItem:
-#endif
if (is_drawable()) {
set_canvas_cursor (_cursors->right_side_trim);
}
break;
}
entered_marker = marker;
- marker->set_color_rgba (ARDOUR_UI::config()->canvasvar_EnteredMarker.get());
+ marker->set_color_rgba (ARDOUR_UI::config()->get_canvasvar_EnteredMarker());
// fall through
case MeterMarkerItem:
case TempoMarkerItem:
case EndSelectionTrimItem:
case PlayheadCursorItem:
-#ifdef WITH_CMT
- case ImageFrameHandleStartItem:
- case ImageFrameHandleEndItem:
- case MarkerViewHandleStartItem:
- case MarkerViewHandleEndItem:
-#endif
-
_over_region_trim_target = false;
if (is_drawable()) {
case FeatureLineItem:
{
ArdourCanvas::Line *line = dynamic_cast<ArdourCanvas::Line *> (item);
- line->set_outline_color (ARDOUR_UI::config()->canvasvar_ZeroLine.get());
+ line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_ZeroLine());
}
break;
}
ControlPointDialog d (p);
- d.set_position (Gtk::WIN_POS_MOUSE);
ensure_float (d);
if (d.run () != RESPONSE_ACCEPT) {
}
void
-Editor::edit_notes (MidiRegionView::Selection const & s)
+Editor::edit_notes (TimeAxisViewItem& tavi)
{
+ MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(&tavi);
+
+ if (!mrv) {
+ return;
+ }
+
+ MidiRegionView::Selection const & s = mrv->selection();
+
if (s.empty ()) {
return;
}
- EditNoteDialog d (&(*s.begin())->region_view(), s);
- d.set_position (Gtk::WIN_POS_MOUSE);
- ensure_float (d);
+ EditNoteDialog* d = new EditNoteDialog (&(*s.begin())->region_view(), s);
+ d->show_all ();
+ ensure_float (*d);
- d.run ();
+ d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &Editor::note_edit_done), d));
}
+void
+Editor::note_edit_done (int r, EditNoteDialog* d)
+{
+ d->done (r);
+ delete d;
+}
void
Editor::visible_order_range (int* low, int* high) const
void
Editor::reposition_zoom_rect (framepos_t start, framepos_t end)
{
- double x1 = frame_to_pixel (start);
- double x2 = frame_to_pixel (end);
+ double x1 = sample_to_pixel (start);
+ double x2 = sample_to_pixel (end);
double y2 = _full_canvas_height - 1.0;
zoom_rect->set (ArdourCanvas::Rect (x1, 1.0, x2, y2));
if (Config->get_edit_mode() == Splice) {
_drags->add (new RegionSpliceDrag (this, item, region_view, selection->regions.by_layer()));
} else {
- RegionSelection s = get_equivalent_regions (selection->regions, ARDOUR::Properties::select.property_id);
- _drags->add (new RegionMoveDrag (this, item, region_view, s.by_layer(), false, false));
+ _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, false));
}
-
- /* sync the canvas to what we think is its current state */
- update_canvas_now();
}
void
_region_motion_group->raise_to_top ();
- RegionSelection s = get_equivalent_regions (selection->regions, ARDOUR::Properties::select.property_id);
- _drags->add (new RegionMoveDrag (this, item, region_view, s.by_layer(), false, true));
+ _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, true));
}
void
return;
}
- RegionSelection s = get_equivalent_regions (selection->regions, ARDOUR::Properties::select.property_id);
- _drags->add (new RegionMoveDrag (this, item, region_view, s.by_layer(), true, false));
+ _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), true, false));
begin_reversible_command (Operations::drag_region_brush);
}
}
/* XXX: maybe we should make entered_track work in all cases, rather than resorting to this */
- pair<TimeAxisView*, int> tvp = trackview_by_y_position (y + vertical_adjustment.get_value());
+ pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
if (tvp.first) {
{
int px, py;
_track_canvas->get_pointer (px, py);
- _track_canvas_viewport->window_to_canvas (px, py, x, y);
+ _track_canvas->window_to_canvas (px, py, x, y);
}