Mercurial > hg > svgui
changeset 550:d666f5f8b154
* Make a better job of picking the proper point to drag, edit, delete etc
in note and region layers
* Some work to do with region dragging, but this still needs more thought
author | Chris Cannam |
---|---|
date | Mon, 28 Sep 2009 12:29:12 +0000 |
parents | e6122e4999a3 |
children | c2ba2796cbee |
files | layer/NoteLayer.cpp layer/NoteLayer.h layer/RegionLayer.cpp layer/RegionLayer.h |
diffstat | 4 files changed, 150 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/NoteLayer.cpp Fri Sep 25 12:02:22 2009 +0000 +++ b/layer/NoteLayer.cpp Mon Sep 28 12:29:12 2009 +0000 @@ -404,6 +404,34 @@ return usePoints; } +bool +NoteLayer::getPointToDrag(View *v, int x, int y, NoteModel::Point &p) const +{ + if (!m_model) return false; + + long frame = v->getFrameForX(x); + + NoteModel::PointList onPoints = m_model->getPoints(frame); + if (onPoints.empty()) return false; + + std::cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << std::endl; + + int nearestDistance = -1; + + for (NoteModel::PointList::const_iterator i = onPoints.begin(); + i != onPoints.end(); ++i) { + + int distance = getYForValue(v, (*i).value) - y; + if (distance < 0) distance = -distance; + if (nearestDistance == -1 || distance < nearestDistance) { + nearestDistance = distance; + p = *i; + } + } + + return true; +} + QString NoteLayer::getFeatureDescription(View *v, QPoint &pos) const { @@ -818,10 +846,12 @@ { if (!m_model) return; - NoteModel::PointList points = getLocalPoints(v, e->x()); - if (points.empty()) return; +// NoteModel::PointList points = getLocalPoints(v, e->x()); +// if (points.empty()) return; - m_editingPoint = *points.begin(); +// m_editingPoint = *points.begin(); + + if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; if (m_editingCommand) { finish(m_editingCommand); @@ -843,13 +873,18 @@ m_editing = false; +/* NoteModel::PointList points = getLocalPoints(v, e->x()); if (points.empty()) return; if (points.begin()->frame != m_editingPoint.frame || points.begin()->value != m_editingPoint.value) return; +*/ - m_editingCommand = new NoteModel::EditCommand - (m_model, tr("Erase Point")); + NoteModel::Point p(0); + if (!getPointToDrag(v, e->x(), e->y(), p)) return; + if (p.frame != m_editingPoint.frame || p.value != m_editingPoint.value) return; + + m_editingCommand = new NoteModel::EditCommand(m_model, tr("Erase Point")); m_editingCommand->deletePoint(m_editingPoint); @@ -865,10 +900,14 @@ if (!m_model) return; +/* NoteModel::PointList points = getLocalPoints(v, e->x()); if (points.empty()) return; m_editingPoint = *points.begin(); +*/ + + if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; m_originalPoint = m_editingPoint; if (m_editingCommand) { @@ -935,11 +974,15 @@ NoteLayer::editOpen(View *v, QMouseEvent *e) { if (!m_model) return false; - +/* NoteModel::PointList points = getLocalPoints(v, e->x()); if (points.empty()) return false; +*/ - NoteModel::Point note = *points.begin(); + NoteModel::Point note(0); + if (!getPointToDrag(v, e->x(), e->y(), note)) return false; + +// NoteModel::Point note = *points.begin(); ItemEditDialog *dialog = new ItemEditDialog (m_model->getSampleRate(),
--- a/layer/NoteLayer.h Fri Sep 25 12:02:22 2009 +0000 +++ b/layer/NoteLayer.h Mon Sep 28 12:29:12 2009 +0000 @@ -135,6 +135,8 @@ NoteModel::PointList getLocalPoints(View *v, int) const; + bool getPointToDrag(View *v, int x, int y, NoteModel::Point &) const; + NoteModel *m_model; bool m_editing; NoteModel::Point m_originalPoint;
--- a/layer/RegionLayer.cpp Fri Sep 25 12:02:22 2009 +0000 +++ b/layer/RegionLayer.cpp Mon Sep 28 12:29:12 2009 +0000 @@ -327,6 +327,32 @@ return usePoints; } +bool +RegionLayer::getPointToDrag(View *v, int x, int y, RegionModel::Point &p) const +{ + if (!m_model) return false; + + long frame = v->getFrameForX(x); + + RegionModel::PointList onPoints = m_model->getPoints(frame); + if (onPoints.empty()) return false; + + int nearestDistance = -1; + + for (RegionModel::PointList::const_iterator i = onPoints.begin(); + i != onPoints.end(); ++i) { + + int distance = getYForValue(v, (*i).value) - y; + if (distance < 0) distance = -distance; + if (nearestDistance == -1 || distance < nearestDistance) { + nearestDistance = distance; + p = *i; + } + } + + return true; +} + QString RegionLayer::getFeatureDescription(View *v, QPoint &pos) const { @@ -760,6 +786,9 @@ textY = v->getTextLabelHeight(this, paint); } + int fontHeight = paint.fontMetrics().height(); + int fontAscent = paint.fontMetrics().ascent(); + for (RegionModel::PointList::const_iterator i = points.begin(); i != points.end(); ++i) { @@ -781,10 +810,9 @@ } if (m_plotStyle != PlotSegmentation) { - textY = y - paint.fontMetrics().height() - + paint.fontMetrics().ascent(); - if (textY < paint.fontMetrics().ascent() + 1) { - textY = paint.fontMetrics().ascent() + 1; + textY = y - fontHeight + fontAscent; + if (textY < fontAscent + 1) { + textY = fontAscent + 1; } } @@ -829,11 +857,11 @@ paint.drawLine(x+w, y - h/2, x + w, y + h/2); } - if (p.label != "") { -// if (ex > x + 6 + paint.fontMetrics().width(p.label)) { - paint.drawText(x + 5, textY, p.label); -// } - } + QString label = p.label; + if (label == "") { + label = QString("[%1]").arg(p.value); + } + v->drawVisibleText(paint, x + 5, textY, label, View::OutlinedText); } paint.restore(); @@ -852,7 +880,7 @@ float value = getValueForY(v, e->y()); - m_editingPoint = RegionModel::Point(frame, value, 0, tr("New Region")); + m_editingPoint = RegionModel::Point(frame, value, 0, ""); m_originalPoint = m_editingPoint; if (m_editingCommand) finish(m_editingCommand); @@ -860,6 +888,8 @@ tr("Draw Region")); m_editingCommand->addPoint(m_editingPoint); + recalcSpacing(); + m_editing = true; } @@ -891,6 +921,8 @@ m_editingPoint.value = newValue; m_editingPoint.duration = newDuration; m_editingCommand->addPoint(m_editingPoint); + +// recalcSpacing(); } void @@ -901,6 +933,8 @@ finish(m_editingCommand); m_editingCommand = 0; m_editing = false; + + recalcSpacing(); } void @@ -908,17 +942,20 @@ { if (!m_model) return; + if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; +/* RegionModel::PointList points = getLocalPoints(v, e->x()); if (points.empty()) return; m_editingPoint = *points.begin(); - +*/ if (m_editingCommand) { finish(m_editingCommand); m_editingCommand = 0; } m_editing = true; + recalcSpacing(); } void @@ -932,11 +969,15 @@ if (!m_model || !m_editing) return; m_editing = false; - +/* RegionModel::PointList points = getLocalPoints(v, e->x()); if (points.empty()) return; if (points.begin()->frame != m_editingPoint.frame || points.begin()->value != m_editingPoint.value) return; +*/ + RegionModel::Point p(0); + if (!getPointToDrag(v, e->x(), e->y(), p)) return; + if (p.frame != m_editingPoint.frame || p.value != m_editingPoint.value) return; m_editingCommand = new RegionModel::EditCommand (m_model, tr("Erase Region")); @@ -946,19 +987,28 @@ finish(m_editingCommand); m_editingCommand = 0; m_editing = false; + recalcSpacing(); } void RegionLayer::editStart(View *v, QMouseEvent *e) { -// std::cerr << "RegionLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; + std::cerr << "RegionLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model) return; - RegionModel::PointList points = getLocalPoints(v, e->x()); - if (points.empty()) return; +// OrderedPointList opoints = getNearbyPoints(v, e->x(), e->y()); +// RegionLayer: - m_editingPoint = *points.begin(); +// RegionModel::PointList points = getLocalPoints(v, e->x()); +// if (points.empty()) return; + +// m_editingPoint = *points.begin(); + + if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) { + return; + } + m_originalPoint = m_editingPoint; if (m_editingCommand) { @@ -967,12 +1017,15 @@ } m_editing = true; + m_dragYOrigin = e->y(); + m_dragYRebase = e->y(); + recalcSpacing(); } void RegionLayer::editDrag(View *v, QMouseEvent *e) { -// std::cerr << "RegionLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; + std::cerr << "RegionLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; @@ -980,23 +1033,31 @@ if (frame < 0) frame = 0; frame = frame / m_model->getResolution() * m_model->getResolution(); - float value = getValueForY(v, e->y()); + int activeY = e->y() + (m_dragYRebase - m_dragYOrigin); + float value = getValueForY(v, activeY); if (!m_editingCommand) { m_editingCommand = new RegionModel::EditCommand(m_model, tr("Drag Region")); } + if (m_verticalScale == EqualSpaced) { + if (getYForValue(v, value) != getYForValue(v, m_editingPoint.value)) { + m_dragYRebase = e->y(); + } + } + m_editingCommand->deletePoint(m_editingPoint); m_editingPoint.frame = frame; m_editingPoint.value = value; m_editingCommand->addPoint(m_editingPoint); + recalcSpacing(); } void -RegionLayer::editEnd(View *, QMouseEvent *) +RegionLayer::editEnd(View *, QMouseEvent *e) { -// std::cerr << "RegionLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; + std::cerr << "RegionLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; if (!m_model || !m_editing) return; if (m_editingCommand) { @@ -1019,17 +1080,22 @@ m_editingCommand = 0; m_editing = false; + recalcSpacing(); } bool RegionLayer::editOpen(View *v, QMouseEvent *e) { if (!m_model) return false; - +/* RegionModel::PointList points = getLocalPoints(v, e->x()); if (points.empty()) return false; +*/ - RegionModel::Point region = *points.begin(); + RegionModel::Point region(0); + if (!getPointToDrag(v, e->x(), e->y(), region)) return false; + +// RegionModel::Point region = *points.begin(); ItemEditDialog *dialog = new ItemEditDialog (m_model->getSampleRate(), @@ -1060,6 +1126,7 @@ } delete dialog; + recalcSpacing(); return true; } @@ -1086,6 +1153,7 @@ } finish(command); + recalcSpacing(); } void @@ -1125,6 +1193,7 @@ } finish(command); + recalcSpacing(); } void @@ -1147,6 +1216,7 @@ } finish(command); + recalcSpacing(); } void @@ -1244,6 +1314,7 @@ } finish(command); + recalcSpacing(); return true; }
--- a/layer/RegionLayer.h Fri Sep 25 12:02:22 2009 +0000 +++ b/layer/RegionLayer.h Mon Sep 28 12:29:12 2009 +0000 @@ -125,10 +125,14 @@ virtual int getDefaultColourHint(bool dark, bool &impose); - RegionModel::PointList getLocalPoints(View *v, int) const; + RegionModel::PointList getLocalPoints(View *v, int x) const; + + bool getPointToDrag(View *v, int x, int y, RegionModel::Point &) const; RegionModel *m_model; bool m_editing; + int m_dragYOrigin; + int m_dragYRebase; RegionModel::Point m_originalPoint; RegionModel::Point m_editingPoint; RegionModel::EditCommand *m_editingCommand;