many substantive changes in the handling of ARDOUR::Location, Markers and drags/clicks on Markers.

It would have been nice to split this commit into parts, but it is all very interconnected and was not possible to
subdivide.
This commit is contained in:
Paul Davis 2014-09-23 10:48:31 -04:00
parent eb7d7bd44f
commit 0472453d94
12 changed files with 544 additions and 397 deletions

View file

@ -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<Locations>(*(_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);

View file

@ -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;

View file

@ -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 ();

View file

@ -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<Marker*> (_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<ArdourCanvas::Rect> 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<Marker*> 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<Locations>(*(_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)

View file

@ -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;
};

View file

@ -63,6 +63,7 @@ enum ItemType {
BBTRulerItem,
SamplesRulerItem,
DropZoneItem,
ClockRulerItem,
/* don't remove this */

View file

@ -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<Marker*>& sorted = _sorted_marker_lists[m->get_parent()];
list<Marker*>::iterator i = std::find (sorted.begin(), sorted.end(), m);
list<Marker*>::iterator prev = sorted.end ();
list<Marker*>::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<ArdourCanvas::Container *, std::list<Marker *> >::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<Marker*>& 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<Marker*>::iterator i = sorted.begin ();
list<Marker*>::iterator prev = sorted.end ();
list<Marker*>::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

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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<Cairo::Surface> _pattern;