X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_canvas.cc;h=2e92a374804a99ad06e6624d7296ac38b29f0d3a;hb=098b0f8a8b904313bc2e9e3147cc3c05fd83f3e6;hp=3ff0cf4c4a50b2380bb7029aeefe79a053322e7c;hpb=601c317d70a03190257577bd867cefc2c70d3275;p=ardour.git diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 3ff0cf4c4a..2e92a37480 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -217,6 +217,8 @@ Editor::initialize_canvas () playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event); + snapped_cursor = new EditorCursor (*this); + _canvas_drop_zone = new ArdourCanvas::Rectangle (hv_scroll_group, ArdourCanvas::Rect (0.0, 0.0, ArdourCanvas::COORD_MAX, 0.0)); /* this thing is transparent */ _canvas_drop_zone->set_fill (false); @@ -304,7 +306,7 @@ Editor::track_canvas_viewport_size_allocated () } update_fixed_rulers(); - redisplay_tempo (false); + redisplay_grid (false); _summary->set_overlays_dirty (); } @@ -371,6 +373,9 @@ Editor::track_canvas_drag_data_received (const RefPtr& context const SelectionData& data, guint info, guint time) { + if (!ARDOUR_UI_UTILS::engine_is_running ()) { + return; + } if (data.get_target() == "regions") { drop_regions (context, x, y, data, info, time); } else { @@ -379,14 +384,14 @@ Editor::track_canvas_drag_data_received (const RefPtr& context } bool -Editor::idle_drop_paths (vector paths, framepos_t frame, double ypos, bool copy) +Editor::idle_drop_paths (vector paths, samplepos_t sample, double ypos, bool copy) { - drop_paths_part_two (paths, frame, ypos, copy); + drop_paths_part_two (paths, sample, ypos, copy); return false; } void -Editor::drop_paths_part_two (const vector& paths, framepos_t frame, double ypos, bool copy) +Editor::drop_paths_part_two (const vector& paths, samplepos_t sample, double ypos, bool copy) { RouteTimeAxisView* tv; @@ -412,15 +417,15 @@ Editor::drop_paths_part_two (const vector& paths, framepos_t frame, doub /* drop onto canvas background: create new tracks */ - frame = 0; + sample = 0; InstrumentSelector is; // instantiation builds instrument-list and sets default. - do_import (midi_paths, Editing::ImportDistinctFiles, ImportAsTrack, SrcBest, SMFTrackName, SMFTempoIgnore, frame, is.selected_instrument()); + do_import (midi_paths, Editing::ImportDistinctFiles, ImportAsTrack, SrcBest, SMFTrackName, SMFTempoIgnore, sample, is.selected_instrument()); if (UIConfiguration::instance().get_only_copy_imported_files() || copy) { do_import (audio_paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, - SrcBest, SMFTrackName, SMFTempoIgnore, frame); + SrcBest, SMFTrackName, SMFTempoIgnore, sample); } else { - do_embed (audio_paths, Editing::ImportDistinctFiles, ImportAsTrack, frame); + do_embed (audio_paths, Editing::ImportDistinctFiles, ImportAsTrack, sample); } } else if ((tv = dynamic_cast (tvp.first)) != 0) { @@ -432,13 +437,13 @@ Editor::drop_paths_part_two (const vector& paths, framepos_t frame, doub selection->set (tv); do_import (midi_paths, Editing::ImportSerializeFiles, ImportToTrack, - SrcBest, SMFTrackName, SMFTempoIgnore, frame); + SrcBest, SMFTrackName, SMFTempoIgnore, sample); if (UIConfiguration::instance().get_only_copy_imported_files() || copy) { do_import (audio_paths, Editing::ImportSerializeFiles, Editing::ImportToTrack, - SrcBest, SMFTrackName, SMFTempoIgnore, frame); + SrcBest, SMFTrackName, SMFTempoIgnore, sample); } else { - do_embed (audio_paths, Editing::ImportSerializeFiles, ImportToTrack, frame); + do_embed (audio_paths, Editing::ImportSerializeFiles, ImportToTrack, sample); } } } @@ -463,7 +468,7 @@ Editor::drop_paths (const RefPtr& context, ev.button.x = x; ev.button.y = y; - MusicFrame when (window_event_sample (&ev, 0, &cy), 0); + MusicSample when (window_event_sample (&ev, 0, &cy), 0); snap_to (when); bool copy = ((context->get_actions() & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY); @@ -472,9 +477,9 @@ Editor::drop_paths (const RefPtr& context, the main event loop with GTK/Quartz. Since import/embed wants to push up a progress dialog, defer all this till we go idle. */ - Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &Editor::idle_drop_paths), paths, when.frame, cy, copy)); + Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &Editor::idle_drop_paths), paths, when.sample, cy, copy)); #else - drop_paths_part_two (paths, when.frame, cy, copy); + drop_paths_part_two (paths, when.sample, cy, copy); #endif } @@ -569,7 +574,7 @@ Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers) toplevel->get_window()->get_pointer (x, y, mask); - if ((allow_horiz && ((x < scrolling_boundary.x0 && leftmost_frame > 0) || x >= scrolling_boundary.x1)) || + if ((allow_horiz && ((x < scrolling_boundary.x0 && _leftmost_sample > 0) || x >= scrolling_boundary.x1)) || (allow_vert && ((y < scrolling_boundary.y0 && vertical_adjustment.get_value() > 0)|| y >= scrolling_boundary.y1))) { start_canvas_autoscroll (allow_horiz, allow_vert, scrolling_boundary); } @@ -581,12 +586,66 @@ Editor::autoscroll_active () const return autoscroll_connection.connected (); } +std::pair +Editor::session_gui_extents (bool use_extra) const +{ + if (!_session) { + return std::pair (max_samplepos,0); + } + + samplecnt_t session_extent_start = _session->current_start_sample(); + samplecnt_t session_extent_end = _session->current_end_sample(); + + /* calculate the extents of all regions in every playlist + * NOTE: we should listen to playlists, and cache these values so we don't calculate them every time. + */ + { + boost::shared_ptr rl = _session->get_routes(); + for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) { + boost::shared_ptr tr = boost::dynamic_pointer_cast (*r); + if (tr) { + boost::shared_ptr pl = tr->playlist(); + if (pl && !pl->all_regions_empty()) { + pair e; + e = pl->get_extent(); + if (e.first < session_extent_start) { + session_extent_start = e.first; + } + if (e.second > session_extent_end) { + session_extent_end = e.second; + } + } + } + } + } + + /* ToDo: also incorporate automation regions (in case the session has no audio/midi but is just used for automating plugins or the like) */ + + /* add additional time to the ui extents (user-defined in config) */ + if (use_extra) { + samplecnt_t const extra = UIConfiguration::instance().get_extra_ui_extents_time() * 60 * _session->nominal_sample_rate(); + session_extent_end += extra; + session_extent_start -= extra; + } + + /* range-check */ + if (session_extent_end > max_samplepos) { + session_extent_end = max_samplepos; + } + if (session_extent_start < 0) { + session_extent_start = 0; + } + + std::pair ret (session_extent_start, session_extent_end); + return ret; +} + bool Editor::autoscroll_canvas () { int x, y; Gdk::ModifierType mask; - frameoffset_t dx = 0; + sampleoffset_t dx = 0; bool no_stop = false; Gtk::Window* toplevel = dynamic_cast(contents().get_toplevel()); @@ -601,7 +660,7 @@ Editor::autoscroll_canvas () if (autoscroll_horizontal_allowed) { - framepos_t new_frame = leftmost_frame; + samplepos_t new_sample = _leftmost_sample; /* horizontal */ @@ -613,10 +672,12 @@ Editor::autoscroll_canvas () dx = pixel_to_sample (dx); - if (leftmost_frame < max_framepos - dx) { - new_frame = leftmost_frame + dx; + dx *= UIConfiguration::instance().get_draggable_playhead_speed(); + + if (_leftmost_sample < max_samplepos - dx) { + new_sample = _leftmost_sample + dx; } else { - new_frame = max_framepos; + new_sample = max_samplepos; } no_stop = true; @@ -628,17 +689,19 @@ Editor::autoscroll_canvas () dx = pixel_to_sample (dx); - if (leftmost_frame >= dx) { - new_frame = leftmost_frame - dx; + dx *= UIConfiguration::instance().get_draggable_playhead_speed(); + + if (_leftmost_sample >= dx) { + new_sample = _leftmost_sample - dx; } else { - new_frame = 0; + new_sample = 0; } no_stop = true; } - if (new_frame != leftmost_frame) { - vc.time_origin = new_frame; + if (new_sample != _leftmost_sample) { + vc.time_origin = new_sample; vc.add (VisualChange::TimeOrigin); } } @@ -912,7 +975,7 @@ Editor::set_horizontal_position (double p) { horizontal_adjustment.set_value (p); - leftmost_frame = (framepos_t) floor (p * samples_per_pixel); + _leftmost_sample = (samplepos_t) floor (p * samples_per_pixel); } void @@ -985,7 +1048,7 @@ Editor::color_handler() _track_canvas->queue_draw (); /* - redisplay_tempo (true); + redisplay_grid (true); if (_session) _session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); // redraw metric markers @@ -995,7 +1058,7 @@ Editor::color_handler() double Editor::horizontal_position () const { - return sample_to_pixel (leftmost_frame); + return sample_to_pixel (_leftmost_sample); } bool @@ -1089,26 +1152,6 @@ Editor::pop_canvas_cursor () } } -Gdk::Cursor* -Editor::which_grabber_cursor () const -{ - Gdk::Cursor* c = _cursors->grabber; - - switch (_edit_point) { - case EditAtMouse: - c = _cursors->grabber_edit_point; - break; - default: - boost::shared_ptr m = _movable.lock(); - if (m && m->locked()) { - c = _cursors->speaker; - } - break; - } - - return c; -} - Gdk::Cursor* Editor::which_trim_cursor (bool left) const { @@ -1208,7 +1251,7 @@ Editor::which_track_cursor () const switch (_join_object_range_state) { case JOIN_OBJECT_RANGE_NONE: case JOIN_OBJECT_RANGE_OBJECT: - cursor = which_grabber_cursor (); + cursor = _cursors->grabber; break; case JOIN_OBJECT_RANGE_RANGE: cursor = _cursors->selector; @@ -1255,14 +1298,7 @@ Editor::which_canvas_cursor(ItemType type) const cursor = which_track_cursor (); break; case PlayheadCursorItem: - switch (_edit_point) { - case EditAtMouse: - cursor = _cursors->grabber_edit_point; - break; - default: - cursor = _cursors->grabber; - break; - } + cursor = _cursors->grabber; break; case SelectionItem: cursor = _cursors->selector; @@ -1304,13 +1340,13 @@ Editor::which_canvas_cursor(ItemType type) const cursor = _cursors->cross_hair; break; case LeftFrameHandle: - if ( effective_mouse_mode() == MouseObject ) // (smart mode): if the user is in the btm half, show the trim cursor + if (effective_mouse_mode() == MouseObject) // (smart mode): if the user is in the btm half, show the trim cursor cursor = which_trim_cursor (true); else - cursor = _cursors->selector; // (smart mode): in the top half, just show the selection (range) cursor + cursor = _cursors->selector; // (smart mode): in the top half, just show the selection (range) cursor break; case RightFrameHandle: - if ( effective_mouse_mode() == MouseObject ) //see above + if (effective_mouse_mode() == MouseObject) // see above cursor = which_trim_cursor (false); else cursor = _cursors->selector; @@ -1372,7 +1408,7 @@ Editor::which_canvas_cursor(ItemType type) const case VideoBarItem: case TransportMarkerBarItem: case DropZoneItem: - cursor = which_grabber_cursor(); + cursor = _cursors->grabber; break; default: