diff options
-rw-r--r-- | muse/muse/waveedit/waveedit.cpp | 35 | ||||
-rw-r--r-- | muse/muse/waveedit/waveedit.h | 1 | ||||
-rw-r--r-- | muse/muse/waveedit/waveview.cpp | 467 | ||||
-rw-r--r-- | muse/muse/waveedit/waveview.h | 38 |
4 files changed, 467 insertions, 74 deletions
diff --git a/muse/muse/waveedit/waveedit.cpp b/muse/muse/waveedit/waveedit.cpp index 9a68b5cf..c54265a0 100644 --- a/muse/muse/waveedit/waveedit.cpp +++ b/muse/muse/waveedit/waveedit.cpp @@ -94,7 +94,10 @@ WaveEdit::WaveEdit(PartList* pl, bool init) tools->addAction(undoAction); tools->addAction(redoAction); - connect(muse, SIGNAL(configChanged()), SLOT(configChanged())); + const int waveeditTools = PointerTool | PencilTool + | RubberTool | DrawTool; + EditToolBar* tools2 = new EditToolBar(this, waveeditTools); + addToolBar(tools2); //-------------------------------------------------- // Transport Bar @@ -130,6 +133,7 @@ WaveEdit::WaveEdit(PartList* pl, bool init) view->setRaster(0); view->setFollow(INIT_FOLLOW); + connect(muse, SIGNAL(configChanged()), SLOT(configChanged())); connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), view, SLOT(setLocatorPos(int,const AL::Pos&,bool))); view->setLocatorPos(0, song->cpos(), true); view->setLocatorPos(1, song->lpos(), false); @@ -146,6 +150,9 @@ WaveEdit::WaveEdit(PartList* pl, bool init) p2 += AL::sigmap.ticksMeasure(p2.tick()); // show one more measure view->setTimeRange(p1, p2); + connect(view, SIGNAL(toolChanged(int)), tools2, SLOT(set(int))); + connect(tools2, SIGNAL(toolChanged(int)), view, SLOT(setTool(int))); + // view->selectFirst(); configChanged(); if (init) @@ -234,6 +241,27 @@ void WaveEdit::keyPressEvent(QKeyEvent* event) } //--------------------------------------------------------- +// read +//--------------------------------------------------------- + +void WaveEdit::read(QDomNode node) + { + for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) { + QDomElement e = node.toElement(); + QString tag(e.tagName()); + if (tag == "CtrlEdit") { + int id = e.attribute("id","0").toInt(); + int h = e.attribute("h","50").toInt(); + view->addController(id, h); + } + else + AL::readProperties(this, node); + } + view->layout1(); + } + + +//--------------------------------------------------------- // write //--------------------------------------------------------- @@ -250,6 +278,11 @@ void WaveEdit::write(Xml& xml) const } xml.stag(metaObject()->className()); xml.writeProperties(this); + const CtrlEditList* el = view->getCtrlEditors(); + for (ciCtrlEdit i = el->begin(); i != el->end(); ++i) { + xml.tagE("CtrlEdit h=\"%d\" id=\"%d\"", + (*i)->height(), (*i)->ctrl()->id()); + } xml.etag(metaObject()->className()); } diff --git a/muse/muse/waveedit/waveedit.h b/muse/muse/waveedit/waveedit.h index 85d9a726..f861587d 100644 --- a/muse/muse/waveedit/waveedit.h +++ b/muse/muse/waveedit/waveedit.h @@ -70,6 +70,7 @@ class WaveEdit : public Editor { WaveEdit(PartList*, bool); ~WaveEdit(); PartList* parts() const { return _parts; } + void read(QDomNode node); void write(Xml& xml) const; enum { CMD_MUTE=0, CMD_NORMALIZE, CMD_FADE_IN, CMD_FADE_OUT, CMD_REVERSE, diff --git a/muse/muse/waveedit/waveview.cpp b/muse/muse/waveedit/waveview.cpp index 1164df87..6659274d 100644 --- a/muse/muse/waveedit/waveview.cpp +++ b/muse/muse/waveedit/waveview.cpp @@ -30,6 +30,8 @@ #include "audio.h" #include "gconfig.h" #include "part.h" +#include "widgets/simplebutton.h" +#include "utils.h" static const int partLabelHeight = 13; @@ -41,6 +43,8 @@ WaveView::WaveView(WaveEdit* pr) : TimeCanvas(TIME_CANVAS_WAVEEDIT) { setMarkerList(song->marker()); + curSplitter = -1; + dragSplitter = false; selectionStart = 0; selectionStop = 0; lastGainvalue = 100; @@ -221,98 +225,184 @@ void WaveView::songChanged(int flags) } //--------------------------------------------------------- -// viewMousePressEvent +// mousePress //--------------------------------------------------------- -void WaveView::viewMousePressEvent(QMouseEvent* /*event*/) +void WaveView::mousePress(QMouseEvent* me) { -#if 0 - button = event->button(); - unsigned x = event->x(); - - switch (button) { - case Qt::LeftButton: - if (mode == NORMAL) { - // redraw and reset: - if (selectionStart != selectionStop) { - selectionStart = selectionStop = 0; - update(); - } - mode = DRAG; - dragstartx = x; - selectionStart = selectionStop = x; - } - break; + QPoint pos(me->pos()); - case Qt::MidButton: - case Qt::RightButton: - default: - break; + if (rCanvasA.contains(pos)) { +// mousePressCanvasA(me); + return; + } + if (curSplitter != -1) { + dragSplitter = true; + splitterY = pos.y(); + return; + } + + if (rCanvasB.contains(pos)) { + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth, + rCanvasB.width(), c->cheight()); + if (r.contains(pos)) { + c->mousePress(pos - r.topLeft(), me->button(), me->modifiers()); + break; + } + } } - viewMouseMoveEvent(event); -#endif } //--------------------------------------------------------- -// viewMouseReleaseEvent +// mouseRelease //--------------------------------------------------------- -void WaveView::viewMouseReleaseEvent(QMouseEvent*) +void WaveView::mouseRelease(QMouseEvent* me) { -#if 0 - button = Qt::NoButton; - - if (mode == DRAG) { - mode = NORMAL; - //printf("selectionStart=%d selectionStop=%d\n", selectionStart, selectionStop); + if (dragSplitter) { + dragSplitter = false; + return; + } + QPoint pos(me->pos()); + if (rCanvasA.contains(pos)) { + // mouseReleaseCanvasA(me); + return; + } + if (rCanvasB.contains(pos)) { + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth, + rCanvasB.width(), c->cheight()); + if (r.contains(pos)) { + c->mouseRelease(); + break; + } + } } -#endif } //--------------------------------------------------------- -// viewMouseMoveEvent +// mouseMove //--------------------------------------------------------- -void WaveView::viewMouseMoveEvent(QMouseEvent* /*event*/) +void WaveView::mouseMove(QPoint pos) { -#if 0 - unsigned x = event->x(); - emit timeChanged(x); - - int i; - switch (button) { - case Qt::LeftButton: - i = 0; - if (mode == DRAG) { - if (x < dragstartx) { - selectionStart = x; - selectionStop = dragstartx; - } - else { - selectionStart = dragstartx; - selectionStop = x; + if (dragSplitter) { + int deltaY = pos.y() - splitterY; + + iCtrlEdit i = ctrlEditList.begin(); + int y = 0; + if (curSplitter > 0) { + int k = 0; + CtrlEdit* c = 0; + for (; i != ctrlEditList.end(); ++i, ++k) { + c = *i; + y += c->height(); + if ((k+1) == curSplitter) + break; + } + if (i == ctrlEditList.end()) { + printf("unexpected edit list end, curSplitter %d\n", curSplitter); + return; + } + if (c->height() + deltaY < splitWidth) + deltaY = splitWidth - c->height(); + ++i; + int rest = 0; + for (iCtrlEdit ii = i; ii != ctrlEditList.end(); ++ii) + rest += (*ii)->cheight(); + if (rest < deltaY) + deltaY = rest; + c->setHeight(c->height() + deltaY); + layoutPanelB(c); + y += deltaY; + } + // + // layout rest, add deltaY vertical + // + int rest = 0; + for (iCtrlEdit ii = i; ii != ctrlEditList.end(); ++ii) { + CtrlEdit* c = *ii; + rest += c->cheight(); + } + if (rest < deltaY) + deltaY = rest; + rest = deltaY; + for (; i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + int d = c->cheight(); + if (d > deltaY) + d = deltaY; + c->setHeight(c->height() - d); + c->y = y; + layoutPanelB(c); + y += c->height(); + deltaY -= d; + if (deltaY == 0) + break; + } + if (i != ctrlEditList.end()) + ++i; + for (; i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + c->y = y; + y += c->height(); + } + if (curSplitter == 0) + resizeController(ctrlHeight - rest); + else + widget()->update(rPanelB | rCanvasB); + splitterY = pos.y(); + updatePartControllerList(); + return; + } + if (rCanvasA.contains(pos)) { + // mouseMoveCanvasA(pos - rCanvasA.topLeft()); + return; + } + if (button == 0) { + if (rPanelB.contains(pos) || rCanvasB.contains(pos)) { + int y = pos.y() - rPanelB.y(); + int k = 0; + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) { + CtrlEdit* c = *i; + if (y >= c->y && y < (c->y + splitWidth)) { + curSplitter = k; + setCursor(); + return; } + int ypos = y - c->y - splitWidth; + if (ypos >= 0) + emit yChanged(c->pixel2val(ypos)); } - break; - case Qt::MidButton: - i = 1; - break; - case Qt::RightButton: - i = 2; - break; - default: - return; + } + if (curSplitter != -1) { + curSplitter = -1; + setCursor(); + } + return; } - Pos p(AL::tempomap.frame2tick(x), true); - song->setPos(i, p); -#endif + if (rCanvasB.contains(pos)) { + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth, + rCanvasB.width(), c->cheight()); + if (r.contains(pos)) { + c->mouseMove(pos - r.topLeft()); + break; + } + } + } + } //--------------------------------------------------------- // cmd //--------------------------------------------------------- -void WaveView::cmd(const QString& c) +void WaveView::cmd(const QString&) { #if 0 int modifyoperation = -1; @@ -786,3 +876,250 @@ void WaveView::range(AL::Pos& s, AL::Pos& e) const e.setFrame(endFrame); } +//--------------------------------------------------------- +// layout +//--------------------------------------------------------- + +void WaveView::layout() + { + int n = ctrlEditList.size(); + if (n == 0) + return; + if (ctrlHeight == 0) { + int wh = widget()->height(); + resizeController(wh < 120 ? wh / 2 : 100); + } + // check, if layout is ok already; this happens after + // song load + int h = 0; + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + h += c->height(); + } + if (h == ctrlHeight) { + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) + layoutPanelB(*i); + return; + } + int y = 0; + int sch = ctrlHeight / n; + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + c->y = y; + c->setHeight(sch); + layoutPanelB(c); + y += sch; + } + } + +//--------------------------------------------------------- +// layout1 +//--------------------------------------------------------- + +void WaveView::layout1() + { + int n = ctrlEditList.size(); + if (n == 0) + return; + int y = 0; + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + c->y = y; + y += c->height(); + } + resizeController(y); + } + +//--------------------------------------------------------- +// layoutPanelB +//--------------------------------------------------------- + +void WaveView::layoutPanelB(CtrlEdit* c) + { + int y = c->y; + int h = c->height(); + int bx = rPanelB.x() + rPanelB.width() - 23; + int by = rPanelB.y() + y + h - 19; + c->minus->setGeometry(bx, by, 18, 18); + bx = rPanelB.x() + 1; + by = rPanelB.y() + y + 5; + c->sel->setGeometry(bx, by, rPanelB.width() - 5, 18); + } + +//--------------------------------------------------------- +// addController +//--------------------------------------------------------- + +void WaveView::addController() + { + int n = ctrlEditList.size(); + CtrlEdit* ce = new CtrlEdit(widget(), this, curPart->track()); + ce->setHeight(50); + ctrlEditList.push_back(ce); + + ce->minus->defaultAction()->setData(n); + connect(ce->minus, SIGNAL(triggered(QAction*)), SLOT(removeController(QAction*))); + ce->minus->show(); + ce->sel->show(); + + layout(); + widget()->update(); + updatePartControllerList(); + } + +void WaveView::addController(int id, int h) + { + ctrlHeight += h; + int n = ctrlEditList.size(); + + CtrlEdit* ce = new CtrlEdit(widget(), this, curPart->track()); + ce->setHeight(h); + ce->setCtrl(id); + ctrlEditList.push_back(ce); + + ce->minus->defaultAction()->setData(n); + connect(ce->minus, SIGNAL(triggered(QAction*)), SLOT(removeController(QAction*))); + } + +//--------------------------------------------------------- +// removeController +//--------------------------------------------------------- + +void WaveView::removeController(QAction* a) + { + int id = a->data().toInt(); + + int k = 0; + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) { + if (k == id) { + CtrlEdit* c = *i; + delete c; + ctrlEditList.erase(i); + break; + } + } + k = 0; + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) { + CtrlEdit* c = *i; + c->minus->defaultAction()->setData(k); + } + + if (ctrlEditList.empty()) + resizeController(0); + else + layout(); + widget()->update(); + updatePartControllerList(); + } + +//--------------------------------------------------------- +// updatePartControllerList +//--------------------------------------------------------- + +void WaveView::updatePartControllerList() + { + if (curPart == 0) + return; + CtrlCanvasList* cl = curPart->getCtrlCanvasList(); + cl->clear(); + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlCanvas cc; + cc.ctrlId = (*i)->ctrlId; + cc.height = (*i)->height(); + cl->push_back(cc); + } + } + +//--------------------------------------------------------- +// paintControllerCanvas +// r(0, 0) is PanelB topLeft() +//--------------------------------------------------------- + +void WaveView::paintControllerCanvas(QPainter& p, QRect r) + { + int x1 = r.x(); + int x2 = x1 + r.width(); + + int xx2 = rCanvasB.width(); + if (xx2 >= x2) + x2 = xx2 - 2; + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + int y = c->y; + paintHLine(p, x1, x2, y); + p.setPen(lineColor[0]); + p.drawLine(xx2-1, 1, xx2-1, splitWidth-2); + + QRect rc(0, y + splitWidth, rCanvasB.width(), c->cheight()); + QPoint pt(rc.topLeft()); + rc &= r; + if (!rc.isEmpty()) { + p.translate(pt); + c->paint(p, rc.translated(-pt)); + p.translate(-pt); + } + } + } + +//--------------------------------------------------------- +// paintControllerPanel +// panelB +//--------------------------------------------------------- + +void WaveView::paintControllerPanel(QPainter& p, QRect r) + { + p.fillRect(r, QColor(0xe0, 0xe0, 0xe0)); + int x1 = r.x(); + int x2 = x1 + r.width(); + + paintVLine(p, r.y() + splitWidth, r.y() + r.height(), + rPanelB.x() + rPanelB.width()); + + if (x1 == 0) + x1 = 1; + for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) { + CtrlEdit* c = *i; + paintHLine(p, x1, x2, c->y); + p.setPen(lineColor[0]); + p.drawLine(0, 1, 0, splitWidth-2); + } + } + +//--------------------------------------------------------- +// setCursor +//--------------------------------------------------------- + +void WaveView::setCursor() + { + if (curSplitter != -1) { + widget()->setCursor(Qt::SplitVCursor); + return; + } + TimeCanvas::setCursor(); + } + +//--------------------------------------------------------- +// enterB +//--------------------------------------------------------- + +void WaveView::enterB() + { + if ((button == 0) && curSplitter != -1) { + curSplitter = -1; + setCursor(); + } + } + +//--------------------------------------------------------- +// leaveB +//--------------------------------------------------------- + +void WaveView::leaveB() + { + if ((button == 0) && (curSplitter != -1)) { + curSplitter = -1; + setCursor(); + } + } + + diff --git a/muse/muse/waveedit/waveview.h b/muse/muse/waveedit/waveview.h index 617a8744..462ce26d 100644 --- a/muse/muse/waveedit/waveview.h +++ b/muse/muse/waveedit/waveview.h @@ -24,6 +24,7 @@ #include "al/pos.h" #include "wave.h" #include "awl/tcanvas.h" +#include "ctrl/ctrledit.h" class PartList; class QPainter; @@ -50,7 +51,10 @@ typedef std::list<WaveEventSelection>::iterator iWaveSelection; //--------------------------------------------------------- class WaveView : public TimeCanvas { + Q_OBJECT + WaveEdit* editor; + CtrlEditList ctrlEditList; int startFrame; int endFrame; @@ -61,16 +65,16 @@ class WaveView : public TimeCanvas { enum { MUTE = 0, NORMALIZE, FADE_IN, FADE_OUT, REVERSE, GAIN, EDIT_EXTERNAL }; //!< Modify operations unsigned selectionStart, selectionStop, dragstartx; + int curSplitter; // -1 mouse not in splitter + bool dragSplitter; + int splitterY; - Q_OBJECT virtual void paint(QPainter&, QRect); - -// virtual void pdraw(QPainter&, const QRect&); -// virtual void draw(QPainter&, const QRect&); - - virtual void viewMousePressEvent(QMouseEvent*); - virtual void viewMouseMoveEvent(QMouseEvent*); - virtual void viewMouseReleaseEvent(QMouseEvent*); + virtual void mousePress(QMouseEvent*); + virtual void mouseMove(QPoint); + virtual void enterB(); + virtual void leaveB(); + virtual void mouseRelease(QMouseEvent*); bool getUniqueTmpfileName(QString& newFilename); //!< Generates unique filename for temporary SndFile WaveSelectionList getSelection(unsigned startpos, unsigned stoppos); @@ -90,15 +94,33 @@ class WaveView : public TimeCanvas { //void applyLadspa(unsigned channels, float** data, unsigned length); //!< Apply LADSPA plugin on selection void drawWavePart(QPainter& p, Part* wp, int y0, int th, int from, int to); + virtual void addController(); + virtual void layout(); + void layoutPanelB(CtrlEdit*); + void updatePartControllerList(); + + virtual void paintControllerCanvas(QPainter&, QRect); + virtual void paintControllerPanel(QPainter&, QRect); + + void setCursor(); + + private slots: + void removeController(QAction*); public slots: void songChanged(int type); + signals: + void yChanged(int); // emitted from mouseMove in controller canvas + public: WaveView(WaveEdit*); QString getCaption() const; void cmd(const QString&); void range(AL::Pos&, AL::Pos&) const; + void addController(int id, int h); + void layout1(); + const CtrlEditList* getCtrlEditors() const { return &ctrlEditList; } }; #endif |