diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index e427ba150b..99ffacf80c 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -4332,8 +4332,6 @@ Editor::set_samples_per_pixel (framecnt_t spp) refresh_location_display(); _summary->set_overlays_dirty (); - update_marker_labels (); - instant_save (); } @@ -4518,6 +4516,7 @@ Editor::set_loop_range (framepos_t start, framepos_t end, string cmd) Location* tll; if ((tll = transport_loop_location()) == 0) { + cerr << "Set loop with new loc\n"; Location* loc = new Location (*_session, start, end, _("Loop"), Location::IsAutoLoop); XMLNode &before = _session->locations()->get_state(); _session->locations()->add (loc, true); @@ -4525,6 +4524,7 @@ Editor::set_loop_range (framepos_t start, framepos_t end, string cmd) XMLNode &after = _session->locations()->get_state(); _session->add_command (new MementoCommand(*(_session->locations()), &before, &after)); } else { + cerr << "Set loop with existing loc " << tll << endl; XMLNode &before = tll->get_state(); tll->set_hidden (false, this); tll->set (start, end); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 560f335fcf..7ba1eaed5c 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -588,17 +588,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD ~LocationMarkers (); - void hide (); - void show (); - - void set_show_lines (bool); - void set_selected (bool); void canvas_height_set (double); - void setup_lines (); - - void set_name (const std::string&); - void set_position (framepos_t start, framepos_t end = 0); - void set_color_rgba (uint32_t); }; LocationMarkers *find_location_markers (ARDOUR::Location *) const; diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 3214df28e6..f6a78ba57c 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -214,7 +214,7 @@ Editor::initialize_canvas () range_bar_drag_rect->set_outline (false); range_bar_drag_rect->hide (); - transport_bar_drag_rect = new ArdourCanvas::Rectangle (transport_marker_group, ArdourCanvas::Rect (0.0, 0.0, 100, timebar_height)); + transport_bar_drag_rect = new ArdourCanvas::Rectangle (ruler_group, ArdourCanvas::Rect (0.0, 0.0, 100, timebar_height)); CANVAS_DEBUG_NAME (transport_bar_drag_rect, "transport drag"); transport_bar_drag_rect->set_outline (false); transport_bar_drag_rect->hide (); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index e4e9e1ce94..081b121108 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3132,6 +3132,367 @@ FadeOutDrag::aborted (bool) } } + +MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i) + : Drag (e, i) + , type (Move) +{ + DEBUG_TRACE (DEBUG::Drags, "New MarkerDrag\n"); + + _marker = reinterpret_cast (_item->get_data ("marker")); + assert (_marker); + + _points.push_back (ArdourCanvas::Duple (0, 0)); + _points.push_back (ArdourCanvas::Duple (0, physical_screen_height (_editor->get_window()))); +} + +MarkerDrag::~MarkerDrag () +{ + for (CopiedLocationInfo::iterator i = _copied_locations.begin(); i != _copied_locations.end(); ++i) { + delete i->location; + } +} + +MarkerDrag::CopiedLocationMarkerInfo::CopiedLocationMarkerInfo (Location* l, Marker* m) +{ + location = new Location (*l); + markers.push_back (m); + move_both = false; +} + +void +MarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) +{ + Drag::start_grab (event, cursor); + + /* event coordinates are in canvas space */ + + boost::optional ro = _marker->the_item().bounding_box(); + assert (ro); + ArdourCanvas::Rect r (*ro); + + r = _marker->the_item().item_to_canvas (r); + + cerr << "From right " << abs (grab_x() - r.x0) << " from left " << abs (grab_x() - r.x1) << endl; + + if (r.width() > 50.0) { + if (abs (grab_x() - r.x0) < 20.0) { + type = TrimLeft; + } else if (abs (grab_x() - r.x1) < 20.0) { + type = TrimRight; + } else { + type = Move; + } + } else { + type = Move; + } + + Location *location = _marker->location(); + _editor->_dragging_edit_point = true; + + if (location) { + + if (location->is_mark()) { + type = Move; + } + + switch (type) { + case TrimLeft: + case Move: + show_verbose_cursor_time (location->start()); + case TrimRight: + default: + show_verbose_cursor_time (location->end()); + } + } + + cerr << "marker drag, type = " << type << endl; + + Selection::Operation op = ArdourKeyboard::selection_type (event->button.state); + + switch (op) { + case Selection::Toggle: + /* we toggle on the button release */ + break; + case Selection::Set: + if (!_editor->selection->selected (_marker)) { + _editor->selection->set (_marker); + } + break; + case Selection::Extend: + { + Locations::LocationList ll; + list to_add; + framepos_t s, e; + _editor->selection->markers.range (s, e); + s = min (_marker->position(), s); + e = max (_marker->position(), e); + s = min (s, e); + e = max (s, e); + if (e < max_framepos) { + ++e; + } + _editor->session()->locations()->find_all_between (s, e, ll, Location::Flags (0)); + for (Locations::LocationList::iterator i = ll.begin(); i != ll.end(); ++i) { + Editor::LocationMarkers* lm = _editor->find_location_markers (*i); + if (lm) { + if (lm->start) { + to_add.push_back (lm->start); + } + if (lm->end) { + to_add.push_back (lm->end); + } + } + } + if (!to_add.empty()) { + _editor->selection->add (to_add); + } + break; + } + case Selection::Add: + _editor->selection->add (_marker); + break; + } + + /* Set up copies for us to manipulate during the drag + */ + + for (MarkerSelection::iterator i = _editor->selection->markers.begin(); i != _editor->selection->markers.end(); ++i) { + + Location* l = (*i)->location(); + + if (!l) { + continue; + } + + if (l->is_mark()) { + _copied_locations.push_back (CopiedLocationMarkerInfo (l, *i)); + } else { + /* range: check that the other end of the range isn't + already there. + */ + CopiedLocationInfo::iterator x; + for (x = _copied_locations.begin(); x != _copied_locations.end(); ++x) { + if (*(*x).location == *l) { + break; + } + } + if (x == _copied_locations.end()) { + _copied_locations.push_back (CopiedLocationMarkerInfo (l, *i)); + } else { + (*x).markers.push_back (*i); + (*x).move_both = true; + } + } + + } +} + +void +MarkerDrag::setup_pointer_frame_offset () +{ + bool is_start; + Location *location = _editor->find_location_from_marker (_marker, is_start); + _pointer_frame_offset = raw_grab_frame() - (is_start ? location->start() : location->end()); +} + +void +MarkerDrag::motion (GdkEvent* event, bool) +{ + framecnt_t f_delta = 0; + Location *real_location; + Location *copy_location = 0; + + framepos_t const newframe = adjusted_current_frame (event); + + CopiedLocationInfo::iterator x; + + /* find the marker we're dragging, and compute the delta */ + + for (x = _copied_locations.begin(); x != _copied_locations.end(); ++x) { + + copy_location = (*x).location; + + if (find (x->markers.begin(), x->markers.end(), _marker) != x->markers.end()) { + + /* this marker is represented by this + * CopiedLocationMarkerInfo + */ + + if ((real_location = _marker->location()) == 0) { + /* que pasa ? */ + return; + } + + switch (type) { + case TrimLeft: + case Move: + f_delta = newframe - copy_location->start(); + cerr << " TL/M fdelta from " << copy_location->end() << " to " << newframe << " = " << f_delta << endl; + break; + case TrimRight: + default: + f_delta = newframe - copy_location->end(); + cerr << "\n\n\nTR fdelta from " << copy_location->end() << " to " << newframe << " = " << f_delta << endl; + break; + } + + break; + } + } + + + if (x == _copied_locations.end()) { + /* hmm, impossible - we didn't find the dragged marker */ + return; + } + + /* now move them all */ + + for (x = _copied_locations.begin(); x != _copied_locations.end(); ++x) { + + copy_location = x->location; + + /* call this to find out if its the start or end */ + + if ((real_location = x->markers.front()->location()) == 0) { + continue; + } + + if (real_location->locked()) { + continue; + } + + if (copy_location->is_mark()) { + + /* now move it */ + + copy_location->set_start (copy_location->start() + f_delta); + + } else { + + framepos_t new_start = copy_location->start() + f_delta; + framepos_t new_end = copy_location->end() + f_delta; + + if (type == Move) { + // _editor->snap_to (new_start, -1, true); + // _editor->snap_to (new_end, -1, true); + cerr << "New : " << new_start << ", " << new_end << endl; + copy_location->set (new_start, new_end); + } else if (type == TrimLeft) { + // _editor->snap_to (new_start, -1, true); + cerr << "New start : " << new_start << endl; + copy_location->set_start (new_start); + } else if (newframe > 0) { + // _editor->snap_to (new_end, -1, true); + cerr << "New end : " << new_end << endl; + copy_location->set_end (new_end); + } + } + + /* doing things this way means that we still obey any logic + in ARDOUR::Location that controls changing position, + but without actually moving the real Location (yet) + */ + + cerr << "MOTION: RESET MARKER TO " << copy_location->start() << " .. " << copy_location->end() << endl; + _marker->set_position (copy_location->start(), copy_location->end()); + } + + assert (!_copied_locations.empty()); + + show_verbose_cursor_time (newframe); +} + +void +MarkerDrag::finished (GdkEvent* event, bool movement_occurred) +{ + if (!movement_occurred) { + + if (was_double_click()) { + _editor->rename_marker (_marker); + return; + } + + /* just a single click */ + + Location* loc = _marker->location (); + if (loc) { + if (loc->is_skip()) { + /* skip range - click toggles active skip status */ + loc->set_skipping (!loc->is_skipping()); + return; + } + } + + /* other markers: do nothing but finish + off the selection process + */ + + Selection::Operation op = ArdourKeyboard::selection_type (event->button.state); + + switch (op) { + case Selection::Set: + if (_editor->selection->selected (_marker) && _editor->selection->markers.size() > 1) { + _editor->selection->set (_marker); + } + break; + + case Selection::Toggle: + /* we toggle on the button release, click only */ + _editor->selection->toggle (_marker); + break; + + case Selection::Extend: + case Selection::Add: + break; + } + + return; + } + + _editor->_dragging_edit_point = false; + + _editor->begin_reversible_command ( _("move marker") ); + XMLNode &before = _editor->session()->locations()->get_state(); + + MarkerSelection::iterator i; + CopiedLocationInfo::iterator x; + bool is_start; + + for (i = _editor->selection->markers.begin(), x = _copied_locations.begin(); + x != _copied_locations.end() && i != _editor->selection->markers.end(); + ++i, ++x) { + + Location * location = _editor->find_location_from_marker (*i, is_start); + + if (location) { + + if (location->locked()) { + return; + } + + if (location->is_mark()) { + location->set_start (((*x).location)->start()); + } else { + location->set (((*x).location)->start(), ((*x).location)->end()); + } + } + } + + XMLNode &after = _editor->session()->locations()->get_state(); + _editor->session()->add_command(new MementoCommand(*(_editor->session()->locations()), &before, &after)); + _editor->commit_reversible_command (); +} + +void +MarkerDrag::aborted (bool) +{ + /* XXX: TODO */ +} + +#if 0 + MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i) : Drag (e, i) { @@ -3512,6 +3873,8 @@ MarkerDrag::update_item (Location*) /* noop */ } +#endif + ControlPointDrag::ControlPointDrag (Editor* e, ArdourCanvas::Item* i) : Drag (e, i), _cumulative_x_drag (0), @@ -4425,27 +4788,13 @@ SelectionDrag::aborted (bool) } RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operation o) - : Drag (e, i, false), - _operation (o), - _copy (false) + : Drag (e, i, false) + , _drag_rect (0) + , _crect (0) + , _operation (o) + , _copy (false) { DEBUG_TRACE (DEBUG::Drags, "New RangeMarkerBarDrag\n"); - - _drag_rect = new ArdourCanvas::Rectangle (_editor->time_line_group, - ArdourCanvas::Rect (0.0, 0.0, 0.0, - physical_screen_height (_editor->get_window()))); - _drag_rect->hide (); - - switch (o) { - case CreateSkipMarker: - _drag_rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SkipDragBarRect()); - _drag_rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_SkipDragBarRect()); - break; - default: - _drag_rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_RangeDragRect()); - _drag_rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_RangeDragRect()); - break; - } } void @@ -4486,71 +4835,83 @@ RangeMarkerBarDrag::motion (GdkEvent* event, bool first_move) { framepos_t start = 0; framepos_t end = 0; - ArdourCanvas::Rectangle *crect; - - switch (_operation) { - case CreateSkipMarker: - crect = _editor->skip_drag_rect; - break; - case CreateRangeMarker: - crect = _editor->range_bar_drag_rect; - break; - case CreateTransportMarker: - crect = _editor->transport_bar_drag_rect; - break; - case CreateCDMarker: - crect = _editor->cd_marker_bar_drag_rect; - break; - default: - error << string_compose (_("programming_error: %1"), "Error: unknown range marker op passed to Editor::drag_range_markerbar_op ()") << endmsg; - return; - break; - } - framepos_t const pf = adjusted_current_frame (event); - if (_operation == CreateSkipMarker || _operation == CreateRangeMarker || _operation == CreateTransportMarker || _operation == CreateCDMarker) { - framepos_t grab = grab_frame (); - _editor->snap_to (grab); + framepos_t grab = grab_frame (); + _editor->snap_to (grab); + + if (pf < grab_frame()) { + start = pf; + end = grab; + } else { + end = pf; + start = grab; + } + + if (first_move) { + + /* Pick the canvas rect that we're going to be dragging */ + + switch (_operation) { + case CreateSkipMarker: + _crect = _editor->skip_drag_rect; + break; + case CreateRangeMarker: + _crect = _editor->range_bar_drag_rect; + break; + case CreateTransportMarker: + cerr << "using transport bar\n"; + _crect = _editor->transport_bar_drag_rect; + break; + case CreateCDMarker: + _crect = _editor->cd_marker_bar_drag_rect; + break; + default: + error << string_compose (_("programming_error: %1"), "Error: unknown range marker op passed to Editor::drag_range_markerbar_op ()") << endmsg; + return; + break; + } - if (pf < grab_frame()) { - start = pf; - end = grab; - } else { - end = pf; - start = grab; - } - - /* first drag: Either add to the selection - or create a new selection. - */ - - if (first_move) { - - _editor->temp_location->set (start, end); - - crect->show (); - - update_item (_editor->temp_location); - _drag_rect->show(); - //_drag_rect->raise_to_top(); - - } - } + /* now a rect to cover the main canvas */ + _drag_rect = new ArdourCanvas::Rectangle (_editor->time_line_group, + ArdourCanvas::Rect (0.0, 0.0, 0.0, + physical_screen_height (_editor->get_window()))); + switch (_operation) { + case CreateSkipMarker: + _drag_rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_SkipDragBarRect()); + _drag_rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_SkipDragBarRect()); + break; + default: + _drag_rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_RangeDragRect()); + _drag_rect->set_outline_color (ARDOUR_UI::config()->get_canvasvar_RangeDragRect()); + break; + } + + _editor->temp_location->set (start, end); + + _crect->show (); + _crect->raise_to_top (); + + _drag_rect->show(); + _drag_rect->raise_to_top(); + } + if (start != end) { _editor->temp_location->set (start, end); - + double x1 = _editor->sample_to_pixel (start); double x2 = _editor->sample_to_pixel (end); - crect->set_x0 (x1); - crect->set_x1 (x2); - - update_item (_editor->temp_location); + + _crect->set_x0 (x1); + _crect->set_x1 (x2); + + _drag_rect->set_x0 (x1); + _drag_rect->set_x1 (x2); } - + + show_verbose_cursor_time (pf); - } void @@ -4563,6 +4924,7 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred) if (movement_occurred) { motion (event, false); _drag_rect->hide(); + _crect->hide (); switch (_operation) { case CreateSkipMarker: @@ -4598,8 +4960,9 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred) } case CreateTransportMarker: - // popup menu to pick loop or punch - _editor->new_transport_marker_context_menu (&event->button, _item); + /* Ardour used to offer a menu to choose between setting loop + autopunch range here */ + cerr << "Setting loop to " << _editor->temp_location->start() << " .. " << _editor->temp_location->end() << endl; + _editor->set_loop_range (_editor->temp_location->start(), _editor->temp_location->end(), _("set loop range")); break; } @@ -4660,16 +5023,6 @@ RangeMarkerBarDrag::aborted (bool) /* XXX: TODO */ } -void -RangeMarkerBarDrag::update_item (Location* location) -{ - double const x1 = _editor->sample_to_pixel (location->start()); - double const x2 = _editor->sample_to_pixel (location->end()); - - _drag_rect->set_x0 (x1); - _drag_rect->set_x1 (x2); -} - MouseZoomDrag::MouseZoomDrag (Editor* e, ArdourCanvas::Item* i) : Drag (e, i) , _zoom_out (false) diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 3c1eef70f6..111d716a35 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -767,9 +767,14 @@ public: void setup_pointer_frame_offset (); private: - void update_item (ARDOUR::Location *); + enum Type { + TrimLeft, + TrimRight, + Move + }; Marker* _marker; ///< marker being dragged + Type type; struct CopiedLocationMarkerInfo { ARDOUR::Location* location; @@ -1017,6 +1022,7 @@ private: Operation _operation; ArdourCanvas::Rectangle* _drag_rect; + ArdourCanvas::Rectangle* _crect; bool _copy; }; diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h index 600565e546..55b65d11d0 100644 --- a/gtk2_ardour/editor_items.h +++ b/gtk2_ardour/editor_items.h @@ -63,6 +63,7 @@ enum ItemType { BBTRulerItem, SamplesRulerItem, DropZoneItem, + ClockRulerItem, /* don't remove this */ diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 654b084636..ce05685fe5 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -65,11 +65,8 @@ Editor::add_new_location (Location *location) { ENSURE_GUI_THREAD (*this, &Editor::add_new_location, location); - ArdourCanvas::Container* group = add_new_location_internal (location); + (void) add_new_location_internal (location); - /* Do a full update of the markers in this group */ - update_marker_labels (group); - if (location->is_auto_punch()) { update_punch_range_view (); } @@ -152,12 +149,6 @@ Editor::add_new_location_internal (Location* location) if (lam->start || lam->end) { - if (location->is_hidden ()) { - lam->hide(); - } else { - lam->show (); - } - location->name_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context()); location->FlagsChanged.connect (*this, invalidator (*this), boost::bind (&Editor::location_flags_changed, this, location), gui_context()); @@ -174,7 +165,6 @@ Editor::add_new_location_internal (Location* location) } lam->canvas_height_set (_visible_canvas_height); - lam->set_show_lines (_show_marker_lines); /* Add these markers to the appropriate sorted marker lists, which will render them unsorted until a call to update_marker_labels() sorts them out. @@ -194,182 +184,11 @@ Editor::add_new_location_internal (Location* location) void Editor::location_changed (Location *location) { - ENSURE_GUI_THREAD (*this, &Editor::location_changed, location) - - LocationMarkers *lam = find_location_markers (location); - - if (lam == 0) { - /* a location that isn't "marked" with markers */ - return; - } - - lam->set_name (location->name ()); - lam->set_position (location->start(), location->end()); - if (location->is_auto_loop()) { update_loop_range_view (); } else if (location->is_auto_punch()) { update_punch_range_view (); } - - check_marker_label (lam->start); - if (lam->end) { - check_marker_label (lam->end); - } -} - -/** Look at a marker and check whether its label, and those of the previous and next markers, - * need to have their labels updated (in case those labels need to be shortened or can be - * lengthened) - */ -void -Editor::check_marker_label (Marker* m) -{ - /* Get a time-ordered list of markers from the last time anything changed */ - std::list& sorted = _sorted_marker_lists[m->get_parent()]; - - list::iterator i = std::find (sorted.begin(), sorted.end(), m); - - list::iterator prev = sorted.end (); - list::iterator next = i; - ++next; - - /* Look to see if the previous marker is still behind `m' in time */ - if (i != sorted.begin()) { - - prev = i; - --prev; - - if ((*prev)->position() > m->position()) { - /* This marker is no longer in the correct order with the previous one, so - * update all the markers in this group. - */ - update_marker_labels (m->get_parent ()); - return; - } - } - - /* Look to see if the next marker is still ahead of `m' in time */ - if (next != sorted.end() && (*next)->position() < m->position()) { - /* This marker is no longer in the correct order with the next one, so - * update all the markers in this group. - */ - update_marker_labels (m->get_parent ()); - return; - } - -#if 0 - if (prev != sorted.end()) { - - /* Update just the available space between the previous marker and this one */ - - double const p = sample_to_pixel (m->position() - (*prev)->position()); - - if (m->label_on_left()) { - (*prev)->set_right_label_limit (p - 4.0); - } else { - (*prev)->set_right_label_limit (p); - } - - if ((*prev)->label_on_left ()) { - m->set_left_label_limit (p); - } else { - m->set_left_label_limit (p - 4.0); - } - } - - if (next != sorted.end()) { - - /* Update just the available space between this marker and the next */ - - double const p = sample_to_pixel ((*next)->position() - m->position()); - - if ((*next)->label_on_left()) { - m->set_right_label_limit (p - 4.0); - } else { - m->set_right_label_limit (p); - } - - if (m->label_on_left()) { - (*next)->set_left_label_limit (p); - } else { - (*next)->set_left_label_limit (p - 4.0); - } - } - -#endif - -} - -struct MarkerComparator { - bool operator() (Marker const * a, Marker const * b) { - return a->position() < b->position(); - } -}; - -/** Update all marker labels in all groups */ -void -Editor::update_marker_labels () -{ - for (std::map >::iterator i = _sorted_marker_lists.begin(); i != _sorted_marker_lists.end(); ++i) { - update_marker_labels (i->first); - } -} - -/** Look at all markers in a group and update label widths */ -void -Editor::update_marker_labels (ArdourCanvas::Container* group) -{ - list& sorted = _sorted_marker_lists[group]; - - if (sorted.empty()) { - return; - } - - /* We sort the list of markers and then set up the space available between each one */ - - sorted.sort (MarkerComparator ()); - - list::iterator i = sorted.begin (); - - list::iterator prev = sorted.end (); - list::iterator next = i; - - if (next != sorted.end()) { - ++next; - } - -#if 0 - - while (i != sorted.end()) { - - if (prev != sorted.end()) { - double const p = sample_to_pixel ((*i)->position() - (*prev)->position()); - - if ((*prev)->label_on_left()) { - (*i)->set_left_label_limit (p); - } else { - (*i)->set_left_label_limit (p / 2); - } - - } - - if (next != sorted.end()) { - double const p = sample_to_pixel ((*next)->position() - (*i)->position()); - - if ((*next)->label_on_left()) { - (*i)->set_right_label_limit (p / 2); - } else { - (*i)->set_right_label_limit (p); - } - - ++next; - } - - prev = i; - ++i; - } -#endif } void @@ -386,12 +205,6 @@ Editor::location_flags_changed (Location *location) // move cd markers to/from cd marker bar as appropriate ensure_cd_marker_updated (lam, location); - - if (location->is_hidden()) { - lam->hide(); - } else { - lam->show (); - } } void Editor::update_cd_marker_display () @@ -538,26 +351,6 @@ Editor::refresh_location_display () if (_session) { _session->locations()->apply (*this, &Editor::refresh_location_display_internal); } - - update_marker_labels (); -} - -void -Editor::LocationMarkers::hide() -{ - start->hide (); - if (end) { - end->hide (); - } -} - -void -Editor::LocationMarkers::show() -{ - start->show (); - if (end) { - end->show (); - } } void @@ -569,74 +362,6 @@ Editor::LocationMarkers::canvas_height_set (double h) } } -void -Editor::LocationMarkers::set_name (const string& str) -{ - /* XXX: hack: don't change names of session start/end markers */ - - if (start->type() != Marker::SessionStart) { - start->set_name (str); - } - - if (end && end->type() != Marker::SessionEnd) { - end->set_name (str); - } -} - -void -Editor::LocationMarkers::set_position (framepos_t startf, - framepos_t endf) -{ - start->set_position (startf); - if (end) { - end->set_position (endf); - } -} - -void -Editor::LocationMarkers::set_color_rgba (uint32_t rgba) -{ -#if 0 - start->set_color_rgba (rgba); - if (end) { - end->set_color_rgba (rgba); - } -#endif -} - -void -Editor::LocationMarkers::set_show_lines (bool s) -{ -#if 0 - start->set_show_line (s); - if (end) { - end->set_show_line (s); - } -#endif -} - -void -Editor::LocationMarkers::set_selected (bool s) -{ -#if 0 - start->set_selected (s); - if (end) { - end->set_selected (s); - } -#endif -} - -void -Editor::LocationMarkers::setup_lines () -{ -#if 0 - start->setup_line (); - if (end) { - end->setup_line (); - } -#endif -} - void Editor::mouse_add_new_marker (framepos_t where, bool is_cd, bool is_xrun) { @@ -1437,18 +1162,17 @@ Editor::update_loop_range_view () return; } - Location* tll; + Location* tll = transport_loop_location(); - if (_session->get_play_loop() && ((tll = transport_loop_location()) != 0)) { + if (_session->get_play_loop() && tll) { double x1 = sample_to_pixel (tll->start()); double x2 = sample_to_pixel (tll->end()); transport_loop_range_rect->set_x0 (x1); transport_loop_range_rect->set_x1 (x2); - + transport_loop_range_rect->show(); - } else { transport_loop_range_rect->hide(); } @@ -1496,11 +1220,11 @@ Editor::marker_selection_changed () return; } +#if 0 for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) { i->second->set_selected (false); } -#if 0 for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) { (*x)->set_selected (true); } @@ -1570,9 +1294,12 @@ Editor::toggle_marker_lines () { _show_marker_lines = !_show_marker_lines; +#if 0 for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) { i->second->set_show_lines (_show_marker_lines); } +#endif + } void diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index ab9e7ea8cf..8a95cd091f 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -674,8 +674,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case SamplesRulerItem: case MinsecRulerItem: case BBTRulerItem: + case ClockRulerItem: if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { - _drags->set (new CursorDrag (this, *playhead_cursor, false), event); + _drags->set (new RangeMarkerBarDrag (this, item, RangeMarkerBarDrag::CreateTransportMarker), event); } return true; break; diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc index 63929494ee..737ea5c26e 100644 --- a/gtk2_ardour/editor_rulers.cc +++ b/gtk2_ardour/editor_rulers.cc @@ -148,7 +148,7 @@ Editor::initialize_rulers () timecode_nmarks = 0; bbt_nmarks = 0; - clock_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), clock_ruler, TimecodeRulerItem)); + clock_ruler->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_event), clock_ruler, ClockRulerItem)); } bool @@ -453,9 +453,11 @@ Editor::update_ruler_visibility () redisplay_tempo (false); /* Changing ruler visibility means that any lines on markers might need updating */ +#if 0 for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) { i->second->setup_lines (); } +#endif } void diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc index a21a9a9274..9a4257183e 100644 --- a/gtk2_ardour/enums.cc +++ b/gtk2_ardour/enums.cc @@ -173,5 +173,7 @@ setup_gtk_ardour_enums () REGISTER_ENUM (MinsecRulerItem); REGISTER_ENUM (BBTRulerItem); REGISTER_ENUM (SamplesRulerItem); + REGISTER_ENUM (ClockRulerItem); + REGISTER_ENUM (DropZoneItem); REGISTER (item_type); } diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index ac8b34c774..abe7e68a56 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -159,15 +159,30 @@ RangeMarker::use_color () } void -RangeMarker::set_position (framepos_t frame) +RangeMarker::_set_position (framepos_t start, framepos_t end) { - Marker::set_position (frame); - double pixel_width = editor.sample_to_pixel (_end_frame - frame_position); - _name_background->set_x1 (_name_background->x0() + pixel_width); - if (_name_item) { - _name_item->clamp_width (pixel_width - _label_offset); + if (end >= 0) { + _end_frame = end; + } + + Marker::_set_position (start, end); + + if (end >= 0) { + + /* clamp displayed length of text to visible marker width + since the marker's visible width is variable depending + on zoom (not true for single-position, non-range markers. + */ + + double pixel_width = editor.sample_to_pixel (_end_frame - frame_position); + _name_background->set_x1 (_name_background->x0() + pixel_width); + + cerr << "reset x1 to " << _name_background->x1() << " based on " << frame_position << " .. " << _end_frame << endl; + + if (_name_item) { + _name_item->clamp_width (pixel_width - _label_offset); + } } - setup_line (); } void @@ -202,6 +217,12 @@ RangeMarker::setup_line () _end_line->show (); } +void +RangeMarker::bounds_changed () +{ + _set_position (_location->start(), _location->end()); +} + void RangeMarker::canvas_height_set (double h) { @@ -250,8 +271,8 @@ Marker::Marker (ARDOUR::Location* l, PublicEditor& ed, ArdourCanvas::Container& , _scene_change_text (0) , frame_position (start_pos) , _type (type) - , _height (height) , _shown (false) + , _height (height) , _color (rgba) , _left_label_limit (DBL_MAX) , _right_label_limit (DBL_MAX) @@ -294,7 +315,13 @@ Marker::Marker (ARDOUR::Location* l, PublicEditor& ed, ArdourCanvas::Container& use_color (); if (_location) { - _location->FlagsChanged.connect (flags_changed_connection, MISSING_INVALIDATOR, boost::bind (&Marker::flags_changed, this), gui_context()); + /* Listen to region properties that we care about */ + + _location->FlagsChanged.connect (location_connections, invalidator(*this), boost::bind (&Marker::flags_changed, this), gui_context()); + _location->NameChanged.connect (location_connections, invalidator(*this), boost::bind (&Marker::name_changed, this), gui_context()); + _location->StartChanged.connect (location_connections, invalidator(*this), boost::bind (&Marker::bounds_changed, this), gui_context()); + _location->EndChanged.connect (location_connections, invalidator(*this), boost::bind (&Marker::bounds_changed, this), gui_context()); + _location->Changed.connect (location_connections, invalidator(*this), boost::bind (&Marker::bounds_changed, this), gui_context()); } } @@ -304,6 +331,8 @@ Marker::~Marker () /* destroying the parent group destroys its contents, namely any polygons etc. that we added */ delete group; + + /* this isn't a child of the group, but belongs to the global canvas hscroll group */ delete _start_line; } @@ -313,10 +342,36 @@ void Marker::reparent(ArdourCanvas::Container & parent) _parent = &parent; } +void +Marker::name_changed () +{ + _name = _location->name(); + setup_name_display (); +} + void Marker::flags_changed () { + /* flags are basically indicate by different coloring, so choose + the right one again. + */ pick_basic_color (0); + + /* location could also have been hidden */ + + if (_location && _location->is_hidden()) { + group->hide (); + } else { + group->show (); + } +} + +void +Marker::bounds_changed () +{ + /* handler can only be invoked if _location was non-null */ + + set_position (_location->start ()); } void @@ -432,6 +487,7 @@ Marker::setup_name_display () } _name_background->set_x0 (0); + /* hard-coded fixed width used if there is no text to display */ _name_background->set_x1 (10); return; @@ -509,7 +565,7 @@ Marker::setup_name_display () } void -Marker::set_position (framepos_t frame) +Marker::_set_position (framepos_t frame, framepos_t) { frame_position = frame; unit_position = editor.sample_to_pixel (frame_position) - _shift; diff --git a/gtk2_ardour/marker.h b/gtk2_ardour/marker.h index 17f0a2c759..8309aab39f 100644 --- a/gtk2_ardour/marker.h +++ b/gtk2_ardour/marker.h @@ -75,7 +75,9 @@ class Marker : public sigc::trackable void set_color (ArdourCanvas::Color); void reset_color (); - virtual void set_position (framepos_t); + void set_position (framepos_t start, framepos_t end = -1) { + return _set_position (start, end); + } framepos_t position() const { return frame_position; } @@ -129,7 +131,12 @@ class Marker : public sigc::trackable double _label_offset; bool _have_scene_change; - void flags_changed (); + virtual void flags_changed (); + virtual void bounds_changed (); + virtual void name_changed (); + + virtual void _set_position (framepos_t, framepos_t); + void pick_basic_color (ArdourCanvas::Color); virtual void use_color (); void reposition (); @@ -143,7 +150,7 @@ private: Marker (Marker const &); Marker & operator= (Marker const &); - PBD::ScopedConnection flags_changed_connection; + PBD::ScopedConnectionList location_connections; }; /** A Marker that displays a range (start+end) rather than a single location @@ -157,11 +164,13 @@ class RangeMarker : public Marker void setup_name_display (); void use_color (); - void set_position (framepos_t); void setup_line (); void canvas_height_set (double); protected: + void bounds_changed (); + void _set_position (framepos_t, framepos_t); + framepos_t _end_frame; ArdourCanvas::Line* _end_line; Cairo::RefPtr _pattern;