|
From: Tapio V. <aa...@us...> - 2011-02-01 16:48:53
|
Module: editor
Branch: master
Commit: 07a345d865a64e2da82838e39b2f5ad6e28898ed
Author: Tapio Vierros <tap...@gm...>
Date: Tue Feb 1 18:45:27 2011 +0200
Note manipulation fixes.
* Moving note to either direction now stops when space runs out
* Resizing to smaller from either end now keeps note fixed at min width
* Enlarging still moves adjacent notes out of the way
- But from the intuitive side (now doesn't look so buggy)
---
notegraphwidget.cc | 31 ++++++++++++++++---------------
notegraphwidget.hh | 4 ++--
notelabel.cc | 8 ++++----
3 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index 166ee8a..4f34b87 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -167,54 +167,55 @@ int NoteGraphWidget::getNoteLabelId(NoteLabel* note) const
return -1;
}
-void NoteGraphWidget::updateNotes()
+void NoteGraphWidget::updateNotes(bool leftToRight)
{
// Here happens the magic that adjusts the floating
// notes according to the fixed ones.
- FloatingGap gap(0);
+ FloatingGap gap(leftToRight ? 0 : width());
// Determine gaps between non-floating notes
- for (NoteLabels::iterator it = m_notes.begin(); it != m_notes.end(); ++it) {
- NoteLabel *child = *it;
+ // Variable leftToRight controls the iteration direction.
+ for (int i = (leftToRight ? 0 : m_notes.size()-1); i >= 0 && i < m_notes.size(); i += (leftToRight ? 1 : -1)) {
+ NoteLabel *child = m_notes[i];
if (!child) continue;
- if (child->isFloating() && child != m_notes.back()) {
+ if (child->isFloating() && i != (leftToRight ? m_notes.size()-1 : 0)) {
// Add floating note to gap
gap.addNote(child);
} else {
// Fixed note encountered, handle the gap (divide notes evenly into it)
- gap.end = child->x();
+ gap.end = child->x() + (leftToRight ? 0 : child->width());
- if (gap.width() <= gap.minWidth()) {
+ int d = (gap.end - gap.begin) * (leftToRight ? 1 : -1);
+ if (d <= gap.minWidth()) {
// We are at minimum width, enforce it
- int x = gap.begin;
+ int x = gap.begin - (leftToRight ? 0 : NoteLabel::min_width);
for (NoteLabels::iterator it2 = gap.notes.begin(); it2 != gap.notes.end(); ++it2) {
(*it2)->move(x, (*it2)->y());
(*it2)->resize(NoteLabel::min_width, (*it2)->height());
- x += NoteLabel::min_width;
+ x += NoteLabel::min_width * (leftToRight ? 1 : -1);
}
- // FIXME: Enforcing fixed note position can be cheated by rapid mouse movement
- // Also, left & right side behave differently
- child->move(gap.begin + gap.minWidth(), child->y());
+ // Also move the fixed one (probably the one being moved by user)
+ child->move(gap.begin + (leftToRight ? gap.minWidth() : (-gap.minWidth() - child->width())), child->y());
} else {
// Calculate position and size
double w = gap.width() / double(gap.notes.size()) * 0.9;
double step = (gap.width() - w * gap.notes.size()) / double(gap.notes.size() + 1);
- double x = gap.begin + step;
+ double x = gap.begin + (leftToRight ? step : (-step - w));
for (NoteLabels::iterator it2 = gap.notes.begin(); it2 != gap.notes.end(); ++it2) {
double y = (*it2)->y();
// Try to find optimal pitch
if (m_pitch) y = n2px(m_pitch->guessNote(px2s(x), px2s(x + w + step), 24)) - m_noteHalfHeight;
(*it2)->move(x, y);
(*it2)->resize(w, (*it2)->height());
- x += w + step;
+ x += (w + step) * (leftToRight ? 1 : -1);
}
}
// Start a new gap
- gap = FloatingGap(child->x() + child->width());
+ gap = FloatingGap(child->x() + (leftToRight ? child->width() : 0));
}
}
}
diff --git a/notegraphwidget.hh b/notegraphwidget.hh
index ba16547..c637a62 100644
--- a/notegraphwidget.hh
+++ b/notegraphwidget.hh
@@ -36,7 +36,7 @@ public:
void setLyrics(QString lyrics);
void setLyrics(const VocalTrack &track);
void analyzeMusic(QString filepath);
- void updateNotes();
+ void updateNotes(bool leftToRight = true);
void updateMusicPos(qint64 time, bool smoothing);
void stopMusic();
@@ -112,7 +112,7 @@ struct FloatingGap
void addNote(NoteLabel* n);
bool isEmpty() const { return notes.empty(); }
- int width() const { return end - begin; }
+ int width() const { return abs(end - begin); }
int minWidth() const;
int notesWidth() const { return m_notesWidth; }
diff --git a/notelabel.cc b/notelabel.cc
index 31c8cb5..b006831 100644
--- a/notelabel.cc
+++ b/notelabel.cc
@@ -99,11 +99,11 @@ void NoteLabel::mouseMoveEvent(QMouseEvent *event)
NoteGraphWidget* ngw = qobject_cast<NoteGraphWidget*>(parent());
if (m_resizing != 0) {
// Resizing
- if (m_resizing < 0)
+ if (m_resizing < 0 && width() - event->pos().x() > min_width)
setGeometry(x() + event->pos().x(), y(), width() - event->pos().x(), height());
- else
+ else if (m_resizing > 0 && event->pos().x() > min_width)
resize(event->pos().x(), height());
- if (ngw) ngw->updateNotes();
+ if (ngw) ngw->updateNotes(m_resizing > 0);
} else if (!m_hotspot.isNull()) {
// Moving
@@ -111,7 +111,7 @@ void NoteLabel::mouseMoveEvent(QMouseEvent *event)
move(newpos);
if (ngw) {
move(x(), ngw->n2px(int(round(ngw->px2n(y() + height() / 2)))) - height() / 2);
- ngw->updateNotes();
+ ngw->updateNotes((event->pos() - m_hotspot).x() < 0);
}
// Check if we need a new hotspot, because the note was constrained
if (pos().x() != newpos.x()) m_hotspot.rx() = event->x();
|