X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_canvas.cc;h=56571c3de886e7c36d52c6fd0bd69f784bb3c820;hb=38e94875647782fa6c28e25be471f0cff6c97d2a;hp=b3668ba194c65d2ac9dde6ff9c3d6d87e17755e3;hpb=9010262bed21611f2db652d16f63e4af4380259d;p=ardour.git diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index b3668ba194..56571c3de8 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -51,10 +51,11 @@ #include "keyboard.h" #include "editor_cursors.h" #include "mouse_cursors.h" +#include "note_base.h" #include "ui_config.h" #include "verbose_cursor.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; @@ -72,6 +73,7 @@ Editor::initialize_canvas () _track_canvas = _track_canvas_viewport->canvas (); _track_canvas->set_background_color (UIConfiguration::instance().color ("arrange base")); + _track_canvas->use_nsglview (); /* scroll group for items that should not automatically scroll * (e.g verbose cursor). It shares the canvas coordinate space. @@ -98,18 +100,6 @@ Editor::initialize_canvas () _verbose_cursor = new VerboseCursor (this); - /* on the bottom, an image */ - - if (Profile->get_sae()) { - Image img (::get_icon (X_("saelogo"))); - // logo_item = new ArdourCanvas::Pixbuf (_track_canvas->root(), 0.0, 0.0, img.get_pixbuf()); - // logo_item->property_height_in_pixels() = true; - // logo_item->property_width_in_pixels() = true; - // logo_item->property_height_set() = true; - // logo_item->property_width_set() = true; - // logo_item->show (); - } - /*a group to hold global rects like punch/loop indicators */ global_rect_group = new ArdourCanvas::Container (hv_scroll_group); CANVAS_DEBUG_NAME (global_rect_group, "global rect group"); @@ -137,7 +127,7 @@ Editor::initialize_canvas () * uppermost (last) group with hv_scroll_group as a parent */ _drag_motion_group = new ArdourCanvas::Container (hv_scroll_group); - CANVAS_DEBUG_NAME (_drag_motion_group, "Canvas Drag Motion"); + CANVAS_DEBUG_NAME (_drag_motion_group, "Canvas Drag Motion"); /* TIME BAR CANVAS */ @@ -184,7 +174,7 @@ Editor::initialize_canvas () cd_marker_bar = new ArdourCanvas::Rectangle (cd_marker_group, ArdourCanvas::Rect (0.0, 0.0, ArdourCanvas::COORD_MAX, timebar_height)); CANVAS_DEBUG_NAME (cd_marker_bar, "CD Marker Bar"); - cd_marker_bar->set_outline_what (ArdourCanvas::Rectangle::BOTTOM); + cd_marker_bar->set_outline_what (ArdourCanvas::Rectangle::BOTTOM); ARDOUR_UI::instance()->video_timeline = new VideoTimeLine(this, videotl_group, (timebar_height * videotl_bar_height)); @@ -227,10 +217,6 @@ Editor::initialize_canvas () playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event); - if (logo_item) { - logo_item->lower_to_bottom (); - } - _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); @@ -255,6 +241,8 @@ Editor::initialize_canvas () _track_canvas->signal_enter_notify_event().connect (sigc::mem_fun(*this, &Editor::entered_track_canvas), false); _track_canvas->set_flags (CAN_FOCUS); + _track_canvas->PreRender.connect (sigc::mem_fun(*this, &Editor::pre_render)); + /* set up drag-n-drop */ vector target_table; @@ -329,17 +317,17 @@ Editor::reset_controls_layout_width () edit_controls_vbox.size_request (req); w = req.width; - if (_group_tabs->is_mapped()) { + if (_group_tabs->is_visible()) { _group_tabs->size_request (req); - w += req.width; - } + w += req.width; + } - /* the controls layout has no horizontal scrolling, its visible - width is always equal to the total width of its contents. - */ + /* the controls layout has no horizontal scrolling, its visible + width is always equal to the total width of its contents. + */ - controls_layout.property_width() = w; - controls_layout.property_width_request() = w; + controls_layout.property_width() = w; + controls_layout.property_width_request() = w; } void @@ -357,11 +345,11 @@ Editor::reset_controls_layout_height (int32_t h) h += _canvas_drop_zone->height (); - /* set the height of the scrollable area (i.e. the sum of all contained widgets) + /* set the height of the scrollable area (i.e. the sum of all contained widgets) * for the controls layout. The size request is set elsewhere. - */ + */ - controls_layout.property_height() = h; + controls_layout.property_height() = h; } @@ -426,10 +414,11 @@ Editor::drop_paths_part_two (const vector& paths, framepos_t frame, doub frame = 0; InstrumentSelector is; // instantiation builds instrument-list and sets default. - do_import (midi_paths, Editing::ImportDistinctFiles, ImportAsTrack, SrcBest, frame, is.selected_instrument()); + do_import (midi_paths, Editing::ImportDistinctFiles, ImportAsTrack, SrcBest, SMFTrackName, SMFTempoIgnore, frame, is.selected_instrument()); - if (Profile->get_sae() || UIConfiguration::instance().get_only_copy_imported_files() || copy) { - do_import (audio_paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, SrcBest, frame); + if (UIConfiguration::instance().get_only_copy_imported_files() || copy) { + do_import (audio_paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, + SrcBest, SMFTrackName, SMFTempoIgnore, frame); } else { do_embed (audio_paths, Editing::ImportDistinctFiles, ImportAsTrack, frame); } @@ -442,10 +431,12 @@ Editor::drop_paths_part_two (const vector& paths, framepos_t frame, doub /* select the track, then embed/import */ selection->set (tv); - do_import (midi_paths, Editing::ImportSerializeFiles, ImportToTrack, SrcBest, frame); + do_import (midi_paths, Editing::ImportSerializeFiles, ImportToTrack, + SrcBest, SMFTrackName, SMFTempoIgnore, frame); - if (Profile->get_sae() || UIConfiguration::instance().get_only_copy_imported_files() || copy) { - do_import (audio_paths, Editing::ImportSerializeFiles, Editing::ImportToTrack, SrcBest, frame); + if (UIConfiguration::instance().get_only_copy_imported_files() || copy) { + do_import (audio_paths, Editing::ImportSerializeFiles, Editing::ImportToTrack, + SrcBest, SMFTrackName, SMFTempoIgnore, frame); } else { do_embed (audio_paths, Editing::ImportSerializeFiles, ImportToTrack, frame); } @@ -461,7 +452,6 @@ Editor::drop_paths (const RefPtr& context, { vector paths; GdkEvent ev; - framepos_t frame; double cy; if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) { @@ -473,19 +463,18 @@ Editor::drop_paths (const RefPtr& context, ev.button.x = x; ev.button.y = y; - frame = window_event_sample (&ev, 0, &cy); - - snap_to (frame); + MusicFrame 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); -#ifdef GTKOSX +#ifdef __APPLE__ /* We are not allowed to call recursive main event loops from within 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, frame, cy, copy)); + Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &Editor::idle_drop_paths), paths, when.frame, cy, copy)); #else - drop_paths_part_two (paths, frame, cy, copy); + drop_paths_part_two (paths, when.frame, cy, copy); #endif } @@ -505,8 +494,8 @@ Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers) if (!toplevel) { return; } - - if (!UIConfiguration::instance()->get_autoscroll_editor () || autoscroll_active ()) { + + if (!UIConfiguration::instance().get_autoscroll_editor () || autoscroll_active ()) { return; } @@ -526,6 +515,16 @@ Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers) if (from_headers) { alloc = controls_layout.get_allocation (); + + int wx, wy; + + controls_layout.get_parent()->translate_coordinates (*toplevel, + alloc.get_x(), alloc.get_y(), + wx, wy); + + scrolling_boundary = ArdourCanvas::Rect (wx, wy, wx + alloc.get_width(), wy + alloc.get_height()); + + } else { alloc = _track_canvas_viewport->get_allocation (); @@ -556,9 +555,14 @@ Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers) alloc.set_x (alloc.get_x() + 10); } - } + int wx, wy; - scrolling_boundary = ArdourCanvas::Rect (alloc.get_x(), alloc.get_y(), alloc.get_x() + alloc.get_width(), alloc.get_y() + alloc.get_height()); + _track_canvas_viewport->get_parent()->translate_coordinates (*toplevel, + alloc.get_x(), alloc.get_y(), + wx, wy); + + scrolling_boundary = ArdourCanvas::Rect (wx, wy, wx + alloc.get_width(), wy + alloc.get_height()); + } int x, y; Gdk::ModifierType mask; @@ -577,6 +581,59 @@ Editor::autoscroll_active () const return autoscroll_connection.connected (); } +std::pair +Editor::session_gui_extents ( bool use_extra ) const +{ + if (!_session) { + return std::pair (max_framepos,0); + } + + framecnt_t session_extent_start = _session->current_start_frame(); + framecnt_t session_extent_end = _session->current_end_frame(); + + //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) { + framecnt_t const extra = UIConfiguration::instance().get_extra_ui_extents_time() * 60 * _session->nominal_frame_rate(); + session_extent_end += extra; + session_extent_start -= extra; + } + + //range-check + if (session_extent_end > max_framepos) { + session_extent_end = max_framepos; + } + if (session_extent_start < 0) { + session_extent_start = 0; + } + + std::pair ret (session_extent_start, session_extent_end); + return ret; +} + bool Editor::autoscroll_canvas () { @@ -608,6 +665,8 @@ Editor::autoscroll_canvas () dx += 10 + (2 * (autoscroll_cnt/2)); dx = pixel_to_sample (dx); + + dx *= UIConfiguration::instance().get_draggable_playhead_speed(); if (leftmost_frame < max_framepos - dx) { new_frame = leftmost_frame + dx; @@ -624,6 +683,8 @@ Editor::autoscroll_canvas () dx = pixel_to_sample (dx); + dx *= UIConfiguration::instance().get_draggable_playhead_speed(); + if (leftmost_frame >= dx) { new_frame = leftmost_frame - dx; } else { @@ -654,6 +715,7 @@ Editor::autoscroll_canvas () scroll_up_one_track (); vertical_motion = true; } + no_stop = true; } else if (y > autoscroll_boundary.y1) { @@ -661,9 +723,9 @@ Editor::autoscroll_canvas () scroll_down_one_track (); vertical_motion = true; } + no_stop = true; } - no_stop = true; } if (vc.pending || vertical_motion) { @@ -744,7 +806,7 @@ Editor::autoscroll_canvas () x = min (max ((ArdourCanvas::Coord) x, autoscroll_boundary.x0), autoscroll_boundary.x1); } y = min (max ((ArdourCanvas::Coord) y, autoscroll_boundary.y0), autoscroll_boundary.y1); - + toplevel->translate_coordinates (*_track_canvas_viewport, x, y, cx, cy); ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (cx, cy)); @@ -773,7 +835,6 @@ Editor::start_canvas_autoscroll (bool allow_horiz, bool allow_vert, const Ardour stop_canvas_autoscroll (); - autoscroll_cnt = 0; autoscroll_horizontal_allowed = allow_horiz; autoscroll_vertical_allowed = allow_vert; autoscroll_boundary = boundary; @@ -792,6 +853,7 @@ void Editor::stop_canvas_autoscroll () { autoscroll_connection.disconnect (); + autoscroll_cnt = 0; } Editor::EnterContext* @@ -806,22 +868,46 @@ Editor::get_enter_context(ItemType type) } bool -Editor::left_track_canvas (GdkEventCrossing */*ev*/) +Editor::left_track_canvas (GdkEventCrossing* ev) { + const bool was_within = within_track_canvas; DropDownKeys (); within_track_canvas = false; set_entered_track (0); set_entered_regionview (0); reset_canvas_action_sensitivity (false); + + if (was_within) { + if (ev->detail == GDK_NOTIFY_NONLINEAR || + ev->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL) { + /* context menu or something similar */ + sensitize_the_right_region_actions (false); + } else { + sensitize_the_right_region_actions (true); + } + } + return false; } bool -Editor::entered_track_canvas (GdkEventCrossing */*ev*/) +Editor::entered_track_canvas (GdkEventCrossing* ev) { + const bool was_within = within_track_canvas; within_track_canvas = true; reset_canvas_action_sensitivity (true); - return FALSE; + + if (!was_within) { + if (ev->detail == GDK_NOTIFY_NONLINEAR || + ev->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL) { + /* context menu or something similar */ + sensitize_the_right_region_actions (false); + } else { + sensitize_the_right_region_actions (true); + } + } + + return false; } void @@ -884,22 +970,13 @@ Editor::set_horizontal_position (double p) horizontal_adjustment.set_value (p); leftmost_frame = (framepos_t) floor (p * samples_per_pixel); - - update_fixed_rulers (); - redisplay_tempo (true); - - if (pending_visual_change.idle_handler_id < 0) { - _summary->set_overlays_dirty (); - } - - update_video_timeline(); } void Editor::color_handler() { - ArdourCanvas::Color base = UIConfiguration::instance().color ("ruler base"); - ArdourCanvas::Color text = UIConfiguration::instance().color ("ruler text"); + Gtkmm2ext::Color base = UIConfiguration::instance().color ("ruler base"); + Gtkmm2ext::Color text = UIConfiguration::instance().color ("ruler text"); timecode_ruler->set_fill_color (base); timecode_ruler->set_outline_color (text); minsec_ruler->set_fill_color (base); @@ -958,6 +1035,8 @@ Editor::color_handler() refresh_location_display (); + NoteBase::set_colors (); + /* redraw the whole thing */ _track_canvas->set_background_color (UIConfiguration::instance().color ("arrange base")); _track_canvas->queue_draw ();