|
From: Tapio V. <aa...@us...> - 2011-01-07 10:34:28
|
Module: editor
Branch: master
Commit: 5eed5f5e32d497fb5af214c02e51a949eb56094c
Author: Tapio Vierros <tap...@gm...>
Date: Fri Jan 7 12:33:55 2011 +0200
Initial floating/fixed note implementation.
* Notes are floating by default.
* Moving a note makes it non-floating (fixed).
* Floating notes are automatically divided
between fixed ones.
* Note width is not yet taken into account.
---
notegraphwidget.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++++-----
notegraphwidget.hh | 24 +++++++++++++++-
notelabel.cc | 20 +++++++++----
notelabel.hh | 14 +++++++++-
4 files changed, 119 insertions(+), 16 deletions(-)
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index 87afe1c..23b1ac8 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -12,17 +12,20 @@ NoteGraphWidget::NoteGraphWidget(QWidget *parent)
void NoteGraphWidget::clear()
{
- const QObjectList &childlist = children ();
+ // Clear NoteLabels
+ const QObjectList &childlist = children();
for (QObjectList::const_iterator it = childlist.begin(); it != childlist.end(); ++it) {
- NoteLabel *child = static_cast<NoteLabel*>(*it);
- child->close();
+ NoteLabel *child = dynamic_cast<NoteLabel*>(*it);
+ if (child) child->close();
}
+ m_notes.clear();
}
void NoteGraphWidget::setLyrics(QString lyrics)
{
QTextStream ts(&lyrics, QIODevice::ReadOnly);
- int x = 5, y = 5;
+ const int gap = 10;
+ int x = gap, y = 50;
clear();
while (!ts.atEnd()) {
@@ -30,17 +33,63 @@ void NoteGraphWidget::setLyrics(QString lyrics)
ts >> word;
if (!word.isEmpty()) {
NoteLabel *wordLabel = new NoteLabel(word, this, QPoint(x, y));
- x += wordLabel->width() + 2;
+ x += wordLabel->width() + gap;
}
}
- requiredWidth = x + 3;
+ rebuildNoteList();
+ // Set first and last to non-floating
+ m_notes.front()->disableFloating();
+ m_notes.back()->disableFloating();
+
+ m_requiredWidth = x + gap;
updateWidth();
}
void NoteGraphWidget::updateWidth()
{
- setFixedWidth(requiredWidth);
+ setFixedWidth(m_requiredWidth);
+}
+
+void NoteGraphWidget::updateNotes()
+{
+ FloatingGap gap(0);
+ rebuildNoteList();
+ // Determine gaps between non-floating notes
+ for (NoteLabels::iterator it = m_notes.begin(); it != m_notes.end(); ++it) {
+ NoteLabel *child = *it; //dynamic_cast<NoteLabel*>(*it);
+ if (!child) continue;
+ std::cout << "Child, floating: " << child->isFloating() << std::endl;
+ if (child->isFloating()) {
+ // Add floating note to gap
+ gap.addNote(child);
+ } else {
+ // Fixed note encountered, handle the gap (divide notes evenly into it)
+ std::cout << "Gap end, width: " << gap.width() << ", notes: " << gap.notes.size() << std::endl;
+ if (!gap.isEmpty()) {
+ gap.end = child->x();
+ int step = gap.width() / (gap.notes.size() + 1);
+ int x = gap.begin + step * 0.5;
+ for (NoteLabels::iterator it2 = gap.notes.begin(); it2 != gap.notes.end(); ++it2, x += step) {
+ (*it2)->move(x, (*it2)->y());
+ }
+ }
+ // Start a new gap
+ gap = FloatingGap(child->x() + child->width());
+ std::cout << "New gap from: " << gap.begin << std::endl;
+ }
+ }
+}
+
+void NoteGraphWidget::rebuildNoteList()
+{
+ m_notes.clear();
+ const QObjectList &childlist = children();
+ for (QObjectList::const_iterator it = childlist.begin(); it != childlist.end(); ++it) {
+ NoteLabel *child = dynamic_cast<NoteLabel*>(*it);
+ if (child) m_notes.push_back(child);
+ }
+ m_notes.sort(cmpNoteLabelPtr);
}
void NoteGraphWidget::dragEnterEvent(QDragEnterEvent *event)
@@ -66,6 +115,8 @@ void NoteGraphWidget::dragMoveEvent(QDragMoveEvent *event)
} else {
event->acceptProposedAction();
}
+ // Update note positions on-the-fly
+ updateNotes();
} else {
event->ignore();
}
@@ -81,7 +132,8 @@ void NoteGraphWidget::dropEvent(QDropEvent *event)
QString text;
QPoint offset;
dataStream >> text >> offset;
- new NoteLabel(text, this, event->pos() - offset);
+ new NoteLabel(text, this, event->pos() - offset, false);
+ updateNotes();
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
@@ -118,6 +170,8 @@ void NoteGraphWidget::mousePressEvent(QMouseEvent *event)
drag->setPixmap(*child->pixmap());
drag->setHotSpot(hotSpot);
+ child->disableFloating();
+ child->createPixmap();
child->hide();
if (drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::CopyAction) == Qt::MoveAction)
@@ -174,3 +228,10 @@ void NoteGraphWidget::mouseDoubleClickEvent(QMouseEvent *event)
event->accept();
}
+
+
+void FloatingGap::addNote(NoteLabel* n)
+{
+ notes.push_back(n);
+ end = n->x();
+}
diff --git a/notegraphwidget.hh b/notegraphwidget.hh
index e261e53..bd5ebc5 100644
--- a/notegraphwidget.hh
+++ b/notegraphwidget.hh
@@ -1,6 +1,10 @@
#pragma once
#include <QWidget>
+#include <list>
+
+class NoteLabel;
+typedef std::list<NoteLabel*> NoteLabels;
class NoteGraphWidget: public QWidget
{
@@ -10,6 +14,8 @@ public:
void clear();
void setLyrics(QString lyrics);
void updateWidth();
+ void updateNotes();
+ void rebuildNoteList();
protected:
void dragEnterEvent(QDragEnterEvent *event);
@@ -20,5 +26,21 @@ protected:
void mouseDoubleClickEvent(QMouseEvent * event);
private:
- int requiredWidth;
+ int m_requiredWidth;
+ NoteLabels m_notes;
+};
+
+
+struct FloatingGap
+{
+ FloatingGap(int x): begin(x), end(x) {}
+
+ void addNote(NoteLabel* n);
+ int width() const { return end - begin; }
+ bool isEmpty() const { return notes.empty(); }
+
+ int begin;
+ int end;
+
+ NoteLabels notes;
};
diff --git a/notelabel.cc b/notelabel.cc
index ae132fb..5839880 100644
--- a/notelabel.cc
+++ b/notelabel.cc
@@ -5,8 +5,8 @@ namespace {
static const int text_margin = 12; // Margin of the label texts
}
-NoteLabel::NoteLabel(const QString &text, QWidget *parent, const QPoint &position)
- : QLabel(parent), m_labelText(text)
+NoteLabel::NoteLabel(const QString &text, QWidget *parent, const QPoint &position, bool floating)
+ : QLabel(parent), m_labelText(text), m_floating(floating)
{
createPixmap();
if (!position.isNull())
@@ -23,6 +23,8 @@ void NoteLabel::createPixmap(QSize size)
size.rwidth() += text_margin;
size.rheight() += text_margin;
}
+ // FIXME: Size is fixed
+ size.rwidth() = 50;
QImage image(size.width(), size.height(),
QImage::Format_ARGB32_Premultiplied);
@@ -33,9 +35,15 @@ void NoteLabel::createPixmap(QSize size)
QLinearGradient gradient(0, 0, 0, image.height()-1);
gradient.setColorAt(0.0, Qt::white);
- gradient.setColorAt(0.2, QColor(200, 200, 255));
- gradient.setColorAt(0.8, QColor(200, 200, 255));
- gradient.setColorAt(1.0, QColor(127, 127, 200));
+ if (m_floating) {
+ gradient.setColorAt(0.2, QColor(160, 160, 180));
+ gradient.setColorAt(0.8, QColor(160, 160, 180));
+ gradient.setColorAt(1.0, QColor(100, 100, 120));
+ } else {
+ gradient.setColorAt(0.2, QColor(100, 100, 255));
+ gradient.setColorAt(0.8, QColor(100, 100, 255));
+ gradient.setColorAt(1.0, QColor(100, 100, 200));
+ }
QPainter painter;
painter.begin(&image);
@@ -57,7 +65,7 @@ void NoteLabel::createPixmap(QSize size)
QString NoteLabel::getText() const
{
- return m_labelText;
+ return m_labelText;
}
void NoteLabel::setText(const QString &text)
diff --git a/notelabel.hh b/notelabel.hh
index 1a7d23a..ad48457 100644
--- a/notelabel.hh
+++ b/notelabel.hh
@@ -5,13 +5,25 @@
class NoteLabel: public QLabel
{
public:
- NoteLabel(const QString &text, QWidget *parent, const QPoint &position = QPoint());
+ NoteLabel(const QString &text, QWidget *parent, const QPoint &position = QPoint(), bool floating = true);
+
void createPixmap(QSize size = QSize());
QString getText() const;
void setText(const QString &text);
+ bool isFloating() const { return m_floating; }
+ void disableFloating() { m_floating = false; }
+
void resizeEvent(QResizeEvent *event);
+ bool operator<(const NoteLabel &rhs) const { return x() < rhs.x(); }
+
private:
QString m_labelText;
+ bool m_floating;
};
+
+bool inline cmpNoteLabelPtr(const NoteLabel *lhs, const NoteLabel *rhs)
+{
+ return *lhs < *rhs;
+}
|