summaryrefslogtreecommitdiff
path: root/attic/muse2-oom/muse2/muse/midiedit/prcanvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse2-oom/muse2/muse/midiedit/prcanvas.cpp')
-rw-r--r--attic/muse2-oom/muse2/muse/midiedit/prcanvas.cpp1864
1 files changed, 0 insertions, 1864 deletions
diff --git a/attic/muse2-oom/muse2/muse/midiedit/prcanvas.cpp b/attic/muse2-oom/muse2/muse/midiedit/prcanvas.cpp
deleted file mode 100644
index 28d0d049..00000000
--- a/attic/muse2-oom/muse2/muse/midiedit/prcanvas.cpp
+++ /dev/null
@@ -1,1864 +0,0 @@
-//=========================================================
-// MusE
-// Linux Music Editor
-// $Id: prcanvas.cpp,v 1.20.2.19 2009/11/16 11:29:33 lunar_shuttle Exp $
-// (C) Copyright 1999-2004 Werner Schweer (ws@seh.de)
-//=========================================================
-
-#include <QApplication>
-#include <QClipboard>
-#include <QPainter>
-#include <QDrag>
-#include <QDragLeaveEvent>
-#include <QDragEnterEvent>
-#include <QDragMoveEvent>
-#include <QDropEvent>
-#include <QMouseEvent>
-
-#include <values.h>
-#include <stdio.h>
-#include <math.h>
-#include <errno.h>
-//#include <sys/stat.h>
-//#include <sys/types.h>
-//#include <sys/mman.h>
-//#include <fcntl.h>
-//#include <dirent.h>
-
-#include "xml.h"
-#include "prcanvas.h"
-#include "midiport.h"
-#include "event.h"
-#include "mpevent.h"
-#include "globals.h"
-#include "cmd.h"
-#include "gatetime.h"
-#include "velocity.h"
-#include "song.h"
-#include "audio.h"
-
-//---------------------------------------------------------
-// NEvent
-//---------------------------------------------------------
-
-NEvent::NEvent(Event& e, Part* p, int y) : CItem(e, p)
- {
- y = y - KH/4;
- unsigned tick = e.tick() + p->tick();
- setPos(QPoint(tick, y));
- setBBox(QRect(tick, y, e.lenTick(), KH/2));
- }
-
-//---------------------------------------------------------
-// addItem
-//---------------------------------------------------------
-
-void PianoCanvas::addItem(Part* part, Event& event)
- {
- if (signed(event.tick())<0) {
- printf("ERROR: trying to add event before current part!\n");
- return;
- }
-
- NEvent* ev = new NEvent(event, part, pitch2y(event.pitch()));
- items.add(ev);
-
- int diff = event.endTick()-part->lenTick();
- if (diff > 0) {// too short part? extend it
- //printf("addItem - this code should not be run!\n");
- //Part* newPart = part->clone();
- //newPart->setLenTick(newPart->lenTick()+diff);
- //audio->msgChangePart(part, newPart,false);
- //part = newPart;
- part->setLenTick(part->lenTick()+diff);
- }
- }
-
-//---------------------------------------------------------
-// PianoCanvas
-//---------------------------------------------------------
-
-PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy)
- : EventCanvas(pr, parent, sx, sy)
- {
- colorMode = 0;
- cmdRange = 0; // all Events
- playedPitch = -1;
-
- songChanged(SC_TRACK_INSERTED);
- connect(song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int)));
- }
-
-//---------------------------------------------------------
-// pitch2y
-//---------------------------------------------------------
-
-int PianoCanvas::pitch2y(int pitch) const
- {
- int tt[] = {
- 5, 12, 19, 26, 33, 44, 51, 58, 64, 71, 78, 85
- };
- int y = (75 * KH) - (tt[pitch%12] + (7 * KH) * (pitch/12));
- if (y < 0)
- y = 0;
- return y;
- }
-
-//---------------------------------------------------------
-// y2pitch
-//---------------------------------------------------------
-
-int PianoCanvas::y2pitch(int y) const
- {
- const int total = (10 * 7 + 5) * KH; // 75 Ganztonschritte
- y = total - y;
- int oct = (y / (7 * KH)) * 12;
- char kt[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
- 1, 1, 1, 1, 1, 1, 1, // 13
- 2, 2, 2, 2, 2, 2, // 19
- 3, 3, 3, 3, 3, 3, 3, // 26
- 4, 4, 4, 4, 4, 4, 4, 4, 4, // 34
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 43
- 6, 6, 6, 6, 6, 6, 6, // 52
- 7, 7, 7, 7, 7, 7, // 58
- 8, 8, 8, 8, 8, 8, 8, // 65
- 9, 9, 9, 9, 9, 9, // 71
- 10, 10, 10, 10, 10, 10, 10, // 78
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 // 87
- };
- return kt[y % 91] + oct;
- }
-
-//---------------------------------------------------------
-// drawEvent
-// draws a note
-//---------------------------------------------------------
-
-void PianoCanvas::drawItem(QPainter& p, const CItem* item,
- const QRect& rect)
-{
- QRect r = item->bbox();
- if(!virt())
- r.moveCenter(map(item->pos()));
- r = r.intersected(rect);
- if(!r.isValid())
- return;
- p.setPen(Qt::black);
- struct Triple
- {
- int r, g, b;
- };
-
- static Triple myColors /*Qt::color1*/[12] =
- { // ddskrjp
- { 0xff, 0x3d, 0x39 },
- { 0x39, 0xff, 0x39 },
- { 0x39, 0x3d, 0xff },
- { 0xff, 0xff, 0x39 },
- { 0xff, 0x3d, 0xff },
- { 0x39, 0xff, 0xff },
- { 0xff, 0x7e, 0x7a },
- { 0x7a, 0x7e, 0xff },
- { 0x7a, 0xff, 0x7a },
- { 0xff, 0x7e, 0xbf },
- { 0x7a, 0xbf, 0xff },
- { 0xff, 0xbf, 0x7a }
- };
-
- QPen mainPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
- p.setPen(mainPen);
-
- QColor colMoving;
- colMoving.setRgb(220, 220, 120, 127);
-
- QPen movingPen(Qt::darkGray, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
-
- QColor colSelected;
- colSelected.setRgb(243, 206, 105, 127);
-
- NEvent* nevent = (NEvent*) item;
- Event event = nevent->event();
- if (nevent->part() != curPart)
- {
- if(item->isMoving())
- {
- p.setPen(movingPen);
- p.setBrush(colMoving);
- }
- else if(item->isSelected())
- {
- p.setPen(mainPen);
- p.setBrush(colSelected);
- }
- else
- {
- p.setPen(movingPen);
- p.setBrush(QColor(192,192,192,127));
- }
- }
- else {
- if (item->isMoving())
- {
- p.setPen(movingPen);
- p.setBrush(colMoving);
- //p.setBrush(Qt::gray);
- }
- else if (item->isSelected())
- {
- p.setPen(mainPen);
- p.setBrush(colSelected);
- }
- else
- {
- QColor color;
- //color.setRgb(80, 102, 143);
- color.setRgb(13,124,151,127);
- switch(colorMode)
- {
- case 0:
- break;
- case 1: // pitch
- {
- Triple* c = &myColors/*Qt::color1*/[event.pitch() % 12];
- color.setRgb(c->r, c->g, c->b, 127);
- }
- break;
- case 2: // velocity
- {
- int velo = event.velo();
- /*
- if (velo < 64)
- color.setRgb(velo*4, 0, 0xff);
- else
- color.setRgb(0xff, 0, (127-velo) * 4);
- */
- /*
- if(velo <= 11)
- color.setRgb(75,145,47);
- else if(velo <= 22)
- color.setRgb(56,145,79);
- else if(velo <= 33)
- color.setRgb(64,139,84);
- else if(velo <= 44)
- color.setRgb(60,137,99);
- else if(velo <= 55)
- color.setRgb(55,134,113);
- else if(velo <= 66)
- color.setRgb(51,132,127);
- else if(velo <= 77)
- color.setRgb(48,130,141);
- else if(velo <= 88)
- color.setRgb(57,121,144);
- else if(velo <= 99)
- color.setRgb(72,108,143);
- else if(velo <= 110)
- color.setRgb(86,96,142);
- else if(velo <= 121)
- color.setRgb(101,84,141);
- else
- color.setRgb(116,72,140);
- */
-
- if(velo <= 11)
- color.setRgb(147,186,195,127);
- else if(velo <= 22)
- color.setRgb(119,169,181,127);
- else if(velo <= 33)
- color.setRgb(85,157,175,127);
- else if(velo <= 44)
- color.setRgb(58,152,176,127);
- else if(velo <= 55)
- color.setRgb(33,137,163,127);
- else if(velo <= 66)
- color.setRgb(30,136,162,127);
- else if(velo <= 77)
- color.setRgb(13,124,151,127);
- else if(velo <= 88)
- color.setRgb(0,110,138,127);
- else if(velo <= 99)
- color.setRgb(0,99,124,127);
- else if(velo <= 110)
- color.setRgb(0,77,96,127);
- else if(velo <= 121)
- color.setRgb(0,69,86,127);
- else
- color.setRgb(0,58,72,127);
-
- }
- break;
- }
- p.setBrush(color);
- }
- }
- p.drawRect(r);
-}
-
-
-//---------------------------------------------------------
-// drawMoving
-// draws moving items
-//---------------------------------------------------------
-
-void PianoCanvas::drawMoving(QPainter& p, const CItem* item, const QRect& rect)
- {
- //if(((NEvent*)item)->part() != curPart)
- // return;
- //if(!item->isMoving())
- // return;
- QRect mr = QRect(item->mp().x(), item->mp().y() - item->height()/2, item->width(), item->height());
- mr = mr.intersected(rect);
- if(!mr.isValid())
- return;
- p.setPen(Qt::black);
- p.setBrush(Qt::NoBrush);
- p.drawRect(mr);
- }
-
-//---------------------------------------------------------
-// viewMouseDoubleClickEvent
-//---------------------------------------------------------
-
-void PianoCanvas::viewMouseDoubleClickEvent(QMouseEvent* event)
- {
- if ((_tool != PointerTool) && (event->button() != Qt::LeftButton)) {
- mousePress(event);
- return;
- }
- }
-
-//---------------------------------------------------------
-// moveCanvasItems
-//---------------------------------------------------------
-
-void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int* pflags)
-{
- if(editor->parts()->empty())
- return;
-
- PartsToChangeMap parts2change;
-
- int modified = 0;
- for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
- {
- Part* part = ip->second;
- if(!part)
- continue;
-
- int npartoffset = 0;
- for(iCItem ici = items.begin(); ici != items.end(); ++ici)
- {
- CItem* ci = ici->second;
- if(ci->part() != part)
- continue;
-
- int x = ci->pos().x() + dx;
- int y = pitch2y(y2pitch(ci->pos().y()) + dp);
- QPoint newpos = raster(QPoint(x, y));
-
- // Test moving the item...
- NEvent* nevent = (NEvent*) ci;
- Event event = nevent->event();
- x = newpos.x();
- if(x < 0)
- x = 0;
- int ntick = editor->rasterVal(x) - part->tick();
- if(ntick < 0)
- ntick = 0;
- int diff = ntick + event.lenTick() - part->lenTick();
-
- // If moving the item would require a new part size...
- if(diff > npartoffset)
- npartoffset = diff;
- }
-
- if(npartoffset > 0)
- {
- // Create new part...
- // if there are several events that are moved outside the part, it will be recreated for each
- // so the part _in_ the event will not be valid, ask the authority.
-// Part* newPart = part->clone();
- //Part* newPart = Canvas::part()->clone();
-
-// newPart->setLenTick(newPart->lenTick() + npartoffset);
- //audio->msgChangePart(part, newPart,false);
-
-// modified = SC_PART_MODIFIED;
-
- // BUG FIX: #1650953
- // Added by T356.
- // Fixes posted "select and drag past end of part - crashing" bug
-// for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
-// {
-// if(ip->second == part)
-// {
-// editor->parts()->erase(ip);
-// break;
-// }
-// }
-
-// editor->parts()->add(newPart);
-// audio->msgChangePart(part, newPart,false);
-
- //if(parts2change.find(part) == parts2change.end())
- // parts2change.insert(std::pair<Part*, Part*> (part, newPart));
- iPartToChange ip2c = parts2change.find(part);
- if(ip2c == parts2change.end())
- {
- PartToChange p2c = {0, npartoffset};
- parts2change.insert(std::pair<Part*, PartToChange> (part, p2c));
- }
- else
- ip2c->second.xdiff = npartoffset;
-
- //part = newPart; // reassign
- //item->setPart(part);
- //item->setEvent(newEvent);
- //curPart = part;
- //curPartId = curPart->sn();
-
- }
- }
-
- for(iPartToChange ip2c = parts2change.begin(); ip2c != parts2change.end(); ++ip2c)
- {
- Part* opart = ip2c->first;
- int diff = ip2c->second.xdiff;
-
- Part* newPart = opart->clone();
-
- newPart->setLenTick(newPart->lenTick() + diff);
-
- modified = SC_PART_MODIFIED;
-
- // BUG FIX: #1650953
- // Added by T356.
- // Fixes posted "select and drag past end of part - crashing" bug
- for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
- {
- if(ip->second == opart)
- {
- editor->parts()->erase(ip);
- break;
- }
- }
-
- editor->parts()->add(newPart);
- // Indicate no undo, and do port controller values but not clone parts.
- audio->msgChangePart(opart, newPart, false, true, false);
-
- ip2c->second.npart = newPart;
-
- }
-
- iPartToChange icp = parts2change.find(curPart);
- if(icp != parts2change.end())
- {
- curPart = icp->second.npart;
- curPartId = curPart->sn();
- }
-
- std::vector< CItem* > doneList;
- typedef std::vector< CItem* >::iterator iDoneList;
-
- for(iCItem ici = items.begin(); ici != items.end(); ++ici)
- {
- CItem* ci = ici->second;
-
- // If this item's part is in the parts2change list, change the item's part to the new part.
- Part* pt = ci->part();
- iPartToChange ip2c = parts2change.find(pt);
- if(ip2c != parts2change.end())
- ci->setPart(ip2c->second.npart);
-
- int x = ci->pos().x();
- int y = ci->pos().y();
- int nx = x + dx;
- int ny = pitch2y(y2pitch(y) + dp);
- QPoint newpos = raster(QPoint(nx, ny));
- selectItem(ci, true);
-
- iDoneList idl;
- for(idl = doneList.begin(); idl != doneList.end(); ++idl)
- // This compares EventBase pointers to see if they're the same...
- if((*idl)->event() == ci->event())
- break;
-
- // Do not process if the event has already been processed (meaning it's an event in a clone part)...
- //if(moveItem(ci, newpos, dtype))
- if(idl != doneList.end())
- // Just move the canvas item.
- ci->move(newpos);
- else
- {
- // Currently moveItem always returns true.
- if(moveItem(ci, newpos, dtype))
- {
- // Add the canvas item to the list of done items.
- doneList.push_back(ci);
- // Move the canvas item.
- ci->move(newpos);
- }
- }
-
- if(moving.size() == 1)
- itemReleased(curItem, newpos);
- if(dtype == MOVE_COPY || dtype == MOVE_CLONE)
- selectItem(ci, false);
- }
-
- if(pflags)
- *pflags = modified;
-}
-
-//---------------------------------------------------------
-// moveItem
-// called after moving an object
-//---------------------------------------------------------
-
-// Changed by T356.
-//bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype, int* pflags)
-bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)
- {
- NEvent* nevent = (NEvent*) item;
- Event event = nevent->event();
- int npitch = y2pitch(pos.y());
- Event newEvent = event.clone();
- int x = pos.x();
- if (x < 0)
- x = 0;
- if (event.pitch() != npitch && _playEvents) {
- int port = track()->outPort();
- int channel = track()->outChannel();
- // release note:
- MidiPlayEvent ev1(0, port, channel, 0x90, event.pitch() + track()->transposition, 0);
- audio->msgPlayMidiEvent(&ev1);
- MidiPlayEvent ev2(0, port, channel, 0x90, npitch + track()->transposition, event.velo());
- audio->msgPlayMidiEvent(&ev2);
- }
-
- // Changed by T356.
- Part* part = nevent->part(); //
- //Part * part = Canvas::part(); // part can be dynamically recreated, ask the authority
-
- newEvent.setPitch(npitch);
- int ntick = editor->rasterVal(x) - part->tick();
- if (ntick < 0)
- ntick = 0;
- newEvent.setTick(ntick);
- newEvent.setLenTick(event.lenTick());
-
- // Removed by T356.
- /*
- int modified=0;
- //song->startUndo();
- int diff = newEvent.endTick()-part->lenTick();
- if (diff > 0){// too short part? extend it
- // if there are several events that are moved outside the part, it will be recreated for each
- // so the part _in_ the event will not be valid, ask the authority.
- //Part* newPart = part->clone();
- Part* newPart = Canvas::part()->clone();
-
- newPart->setLenTick(newPart->lenTick()+diff);
- audio->msgChangePart(Canvas::part(), newPart,false);
-
- modified = SC_PART_MODIFIED;
- part = newPart; // reassign
-
- // BUG FIX: #1650953
- // Added by T356.
- // Fixes posted "select and drag past end of part - crashing" bug
- for(iPart i = editor->parts()->begin(); i != editor->parts()->end(); ++i)
- {
- if(i->second == Canvas::part())
- {
- editor->parts()->erase(i);
- break;
- }
- }
- editor->parts()->add(part);
- item->setPart(part);
- item->setEvent(newEvent);
- curPart = part;
- curPartId = curPart->sn();
-
- }
- */
-
- // Added by T356.
- // msgAddEvent and msgChangeEvent (below) will set these, but set them here first?
- //item->setPart(part);
- item->setEvent(newEvent);
-
- // Added by T356.
- if(((int)newEvent.endTick() - (int)part->lenTick()) > 0)
- printf("PianoCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData());
-
- if (dtype == MOVE_COPY || dtype == MOVE_CLONE)
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgAddEvent(newEvent, part, false);
- audio->msgAddEvent(newEvent, part, false, false, false);
- else
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, part, false);
- audio->msgChangeEvent(event, newEvent, part, false, false, false);
- //song->endUndo(modified);
-
- // Removed by T356.
- //if(pflags)
- // *pflags = modified;
-
- return true;
- }
-
-//---------------------------------------------------------
-// newItem(p, state)
-//---------------------------------------------------------
-
-CItem* PianoCanvas::newItem(const QPoint& p, int)
- {
- //printf("newItem point\n");
- int pitch = y2pitch(p.y());
- int tick = editor->rasterVal1(p.x());
- int len = p.x() - tick;
- tick -= curPart->tick();
- if (tick < 0)
- tick=0;
- Event e = Event(Note);
- e.setTick(tick);
- e.setPitch(pitch);
- e.setVelo(curVelo);
- e.setLenTick(len);
- return new NEvent(e, curPart, pitch2y(pitch));
- }
-
-void PianoCanvas::newItem(CItem* item, bool noSnap)
- {
- //printf("newItem citem\n");
- NEvent* nevent = (NEvent*) item;
- Event event = nevent->event();
- int x = item->x();
- if (x<0)
- x=0;
- int w = item->width();
-
- if (!noSnap) {
- x = editor->rasterVal1(x); //round down
- w = editor->rasterVal(x + w) - x;
- if (w == 0)
- w = editor->raster();
- }
- Part* part = nevent->part();
- event.setTick(x - part->tick());
- event.setLenTick(w);
- event.setPitch(y2pitch(item->y()));
-
- song->startUndo();
- int modified=SC_EVENT_MODIFIED;
- int diff = event.endTick()-part->lenTick();
- if (diff > 0) {// too short part? extend it
- //printf("extend Part!\n");
- Part* newPart = part->clone();
- newPart->setLenTick(newPart->lenTick()+diff);
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgChangePart(part, newPart,false);
- audio->msgChangePart(part, newPart, false, true, false);
- modified=modified|SC_PART_MODIFIED;
- part = newPart; // reassign
- }
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgAddEvent(event, part,false);
- audio->msgAddEvent(event, part, false, false, false);
- song->endUndo(modified);
- }
-
-//---------------------------------------------------------
-// resizeItem
-//---------------------------------------------------------
-
-void PianoCanvas::resizeItem(CItem* item, bool noSnap) // experimental changes to try dynamically extending parts
- {
- //printf("resizeItem!\n");
- NEvent* nevent = (NEvent*) item;
- Event event = nevent->event();
- Event newEvent = event.clone();
- int len;
-
- Part* part = nevent->part();
-
- if (noSnap)
- len = nevent->width();
- else {
- //Part* part = nevent->part();
- unsigned tick = event.tick() + part->tick();
- len = editor->rasterVal(tick + nevent->width()) - tick;
- if (len <= 0)
- len = editor->raster();
- }
- song->startUndo();
- int modified=SC_EVENT_MODIFIED;
- //printf("event.tick()=%d len=%d part->lenTick()=%d\n",event.endTick(),len,part->lenTick());
- int diff = event.tick()+len-part->lenTick();
- if (diff > 0) {// too short part? extend it
- //printf("extend Part!\n");
- Part* newPart = part->clone();
- newPart->setLenTick(newPart->lenTick()+diff);
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgChangePart(part, newPart,false);
- audio->msgChangePart(part, newPart, false, true, false);
- modified=modified|SC_PART_MODIFIED;
- part = newPart; // reassign
- }
-
- newEvent.setLenTick(len);
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, nevent->part(),false);
- audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false);
- song->endUndo(modified);
- }
-
-//---------------------------------------------------------
-// deleteItem
-//---------------------------------------------------------
-
-bool PianoCanvas::deleteItem(CItem* item)
- {
- NEvent* nevent = (NEvent*) item;
- if (nevent->part() == curPart) {
- Event ev = nevent->event();
- // Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, curPart);
- audio->msgDeleteEvent(ev, curPart, true, false, false);
- return true;
- }
- return false;
- }
-
-//---------------------------------------------------------
-// pianoCmd
-//---------------------------------------------------------
-
-void PianoCanvas::pianoCmd(int cmd)
- {
- switch(cmd) {
- case CMD_LEFT:
- {
- int spos = pos[0];
- if(spos > 0)
- {
- spos -= 1; // Nudge by -1, then snap down with raster1.
- spos = AL::sigmap.raster1(spos, editor->rasterStep(pos[0]));
- }
- if(spos < 0)
- spos = 0;
- Pos p(spos,true);
- song->setPos(0, p, true, true, true);
- }
- break;
- case CMD_RIGHT:
- {
- int spos = AL::sigmap.raster2(pos[0] + 1, editor->rasterStep(pos[0])); // Nudge by +1, then snap up with raster2.
- Pos p(spos,true);
- song->setPos(0, p, true, true, true);
- }
- break;
- case CMD_LEFT_NOSNAP:
- {
- int spos = pos[0] - editor->rasterStep(pos[0]);
- if (spos < 0)
- spos = 0;
- Pos p(spos,true);
- song->setPos(0, p, true, true, true); //CDW
- }
- break;
- case CMD_RIGHT_NOSNAP:
- {
- Pos p(pos[0] + editor->rasterStep(pos[0]), true);
- //if (p > part->tick())
- // p = part->tick();
- song->setPos(0, p, true, true, true); //CDW
- }
- break;
- case CMD_INSERT:
- {
- if (pos[0] < start() || pos[0] >= end())
- break;
- MidiPart* part = (MidiPart*)curPart;
-
- if (part == 0)
- break;
- song->startUndo();
- EventList* el = part->events();
-
- std::list <Event> elist;
- for (iEvent e = el->lower_bound(pos[0] - part->tick()); e != el->end(); ++e)
- elist.push_back((Event)e->second);
- for (std::list<Event>::iterator i = elist.begin(); i != elist.end(); ++i) {
- Event event = *i;
- Event newEvent = event.clone();
- newEvent.setTick(event.tick() + editor->raster());// - part->tick());
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, part, false);
- audio->msgChangeEvent(event, newEvent, part, false, false, false);
- }
- song->endUndo(SC_EVENT_MODIFIED);
- Pos p(editor->rasterVal(pos[0] + editor->rasterStep(pos[0])), true);
- song->setPos(0, p, true, false, true);
- }
- return;
- case CMD_DELETE:
- if (pos[0] < start() || pos[0] >= end())
- break;
- {
- MidiPart* part = (MidiPart*)curPart;
- if (part == 0)
- break;
- song->startUndo();
- EventList* el = part->events();
-
- std::list<Event> elist;
- for (iEvent e = el->lower_bound(pos[0]); e != el->end(); ++e)
- elist.push_back((Event)e->second);
- for (std::list<Event>::iterator i = elist.begin(); i != elist.end(); ++i) {
- Event event = *i;
- Event newEvent = event.clone();
- newEvent.setTick(event.tick() - editor->raster() - part->tick());
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, part, false);
- audio->msgChangeEvent(event, newEvent, part, false, false, false);
- }
- song->endUndo(SC_EVENT_MODIFIED);
- Pos p(editor->rasterVal(pos[0] - editor->rasterStep(pos[0])), true);
- song->setPos(0, p, true, false, true);
- }
- break;
- }
- }
-
-//---------------------------------------------------------
-// pianoPressed
-//---------------------------------------------------------
-
-void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift)
- {
- int port = track()->outPort();
- int channel = track()->outChannel();
- pitch += track()->transposition;
-
- // play note:
- //MidiPlayEvent e(0, port, channel, 0x90, pitch, 127);
- MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
- audio->msgPlayMidiEvent(&e);
-
- if (_steprec && pos[0] >= start_tick && pos[0] < end_tick) {
- if (curPart == 0)
- return;
- int len = editor->raster();
- unsigned tick = pos[0] - curPart->tick(); //CDW
- if (shift)
- tick -= editor->rasterStep(tick);
- Event e(Note);
- e.setTick(tick);
- e.setPitch(pitch);
- e.setVelo(127);
- e.setLenTick(len);
- // Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgAddEvent(e, curPart);
- audio->msgAddEvent(e, curPart, true, false, false);
- tick += editor->rasterStep(tick) + curPart->tick();
- if (tick != song->cpos()) {
- Pos p(tick, true);
- song->setPos(0, p, true, false, true);
- }
- }
- }
-
-//---------------------------------------------------------
-// pianoReleased
-//---------------------------------------------------------
-
-void PianoCanvas::pianoReleased(int pitch, bool)
- {
- int port = track()->outPort();
- int channel = track()->outChannel();
- pitch += track()->transposition;
-
- // release key:
- MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
- audio->msgPlayMidiEvent(&e);
- }
-
-//---------------------------------------------------------
-// drawTickRaster
-//---------------------------------------------------------
-
-void drawTickRaster(QPainter& p, int x, int y, int w, int h, int raster)
-{
-
- QColor colBeat;
- colBeat.setRgb(210, 216, 219);
- QColor colBar1;
- colBar1.setRgb(82,85,87);
- QColor colBar2;
- colBar2.setRgb(150,160,167);
-
-
- int bar1, bar2, beat;
- unsigned tick;
- AL::sigmap.tickValues(x, &bar1, &beat, &tick);
- AL::sigmap.tickValues(x+w, &bar2, &beat, &tick);
- ++bar2;
- int y2 = y + h;
- for (int bar = bar1; bar < bar2; ++bar) {
- unsigned x = AL::sigmap.bar2tick(bar, 0, 0);
- p.setPen(colBar1);
- p.drawLine(x, y, x, y2);
- int z, n;
- AL::sigmap.timesig(x, z, n);
- ///int q = p.xForm(QPoint(raster, 0)).x() - p.xForm(QPoint(0, 0)).x();
- int q = p.combinedTransform().map(QPoint(raster, 0)).x() - p.combinedTransform().map(QPoint(0, 0)).x();
- int qq = raster;
- if (q < 8) // grid too dense
- qq *= 2;
- //switch (quant) {
- // case 32:
- // case 48:
- // case 64:
- // case 96:
- // case 192: // 8tel
- // case 128: // 8tel Triolen
- // case 288:
- p.setPen(colBeat);
- if (raster>=4)
- {
- int xx = x + qq;
- int xxx = AL::sigmap.bar2tick(bar, z, 0);
- while (xx <= xxx) {
- p.drawLine(xx, y, xx, y2);
- xx += qq;
- }
- xx = xxx;
- }
- // break;
- // default:
- // break;
- // }
- p.setPen(colBar2);
- for (int beat = 1; beat < z; beat++)
- {
- int xx = AL::sigmap.bar2tick(bar, beat, 0);
- p.drawLine(xx, y, xx, y2);
- }
-
- }
-}
-
-//---------------------------------------------------------
-// draw
-//---------------------------------------------------------
-
-void PianoCanvas::drawCanvas(QPainter& p, const QRect& rect)
- {
- int x = rect.x();
- int y = rect.y();
- int w = rect.width();
- int h = rect.height();
-
- //---------------------------------------------------
- // horizontal lines
- //---------------------------------------------------
-
- int yy = ((y-1) / KH) * KH + KH;
- int key = 75 - (yy / KH);
- for (; yy < y + h; yy += KH)
- {
- switch (key % 7)
- {
- case 0:
- case 3:
- p.setPen(QColor(213,220,213));
- p.drawLine(x, yy, x + w, yy);
- break;
- default:
- //p.setPen(lightGray);
- //p.fillRect(x, yy-3, w, 6, QBrush(QColor(230,230,230)));
- p.fillRect(x, yy-3, w, 6, QBrush(QColor(209,213,209)));
- //p.drawLine(x, yy, x + w, yy);
- break;
- }
- --key;
- }
-
- //---------------------------------------------------
- // vertical lines
- //---------------------------------------------------
-
- drawTickRaster(p, x, y, w, h, editor->raster());
-}
-
-//---------------------------------------------------------
-// cmd
-// pulldown menu commands
-//---------------------------------------------------------
-
-void PianoCanvas::cmd(int cmd, int quantStrength,
- int quantLimit, bool quantLen, int range)
- {
- cmdRange = range;
- printf("PianoCanvas cmd called with command: %d\n\n", cmd);
- switch (cmd) {
- case CMD_CUT:
- copy();
- song->startUndo();
- for (iCItem i = items.begin(); i != items.end(); ++i) {
- if (!(i->second->isSelected()))
- continue;
- NEvent* e = (NEvent*)(i->second);
- Event ev = e->event();
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, e->part(), false);
- audio->msgDeleteEvent(ev, e->part(), false, false, false);
- }
- song->endUndo(SC_EVENT_REMOVED);
- break;
- case CMD_COPY:
- copy();
- break;
- case CMD_PASTE:
- paste();
- break;
- case CMD_DEL:
- if (selectionSize()) {
- song->startUndo();
- for (iCItem i = items.begin(); i != items.end(); ++i) {
- if (!i->second->isSelected())
- continue;
- Event ev = i->second->event();
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, i->second->part(), false);
- audio->msgDeleteEvent(ev, i->second->part(), false, false, false);
- }
- song->endUndo(SC_EVENT_REMOVED);
- }
- return;
- case CMD_OVER_QUANTIZE: // over quantize
- quantize(100, 1, quantLen);
- break;
- case CMD_ON_QUANTIZE: // note on quantize
- quantize(50, 1, false);
- break;
- case CMD_ONOFF_QUANTIZE: // note on/off quantize
- quantize(50, 1, true);
- break;
- case CMD_ITERATIVE_QUANTIZE: // Iterative Quantize
- quantize(quantStrength, quantLimit, quantLen);
- break;
- case CMD_SELECT_ALL: // select all
- for (iCItem k = items.begin(); k != items.end(); ++k) {
- if (!k->second->isSelected())
- selectItem(k->second, true);
- }
- break;
- case CMD_SELECT_NONE: // select none
- deselectAll();
- break;
- case CMD_SELECT_INVERT: // invert selection
- for (iCItem k = items.begin(); k != items.end(); ++k) {
- selectItem(k->second, !k->second->isSelected());
- }
- break;
- case CMD_SELECT_ILOOP: // select inside loop
- for (iCItem k = items.begin(); k != items.end(); ++k) {
- NEvent* nevent = (NEvent*)(k->second);
- Part* part = nevent->part();
- Event event = nevent->event();
- unsigned tick = event.tick() + part->tick();
- if (tick < song->lpos() || tick >= song->rpos())
- selectItem(k->second, false);
- else
- selectItem(k->second, true);
- }
- break;
- case CMD_SELECT_OLOOP: // select outside loop
- for (iCItem k = items.begin(); k != items.end(); ++k) {
- NEvent* nevent = (NEvent*)(k->second);
- Part* part = nevent->part();
- Event event = nevent->event();
- unsigned tick = event.tick() + part->tick();
- if (tick < song->lpos() || tick >= song->rpos())
- selectItem(k->second, true);
- else
- selectItem(k->second, false);
- }
- break;
- case CMD_SELECT_PREV_PART: // select previous part
- {
- Part* pt = editor->curCanvasPart();
- Part* newpt = pt;
- PartList* pl = editor->parts();
- for(iPart ip = pl->begin(); ip != pl->end(); ++ip)
- if(ip->second == pt)
- {
- if(ip == pl->begin())
- ip = pl->end();
- --ip;
- newpt = ip->second;
- break;
- }
- if(newpt != pt)
- editor->setCurCanvasPart(newpt);
- }
- break;
- case CMD_SELECT_NEXT_PART: // select next part
- {
- Part* pt = editor->curCanvasPart();
- Part* newpt = pt;
- PartList* pl = editor->parts();
- for(iPart ip = pl->begin(); ip != pl->end(); ++ip)
- if(ip->second == pt)
- {
- ++ip;
- if(ip == pl->end())
- ip = pl->begin();
- newpt = ip->second;
- break;
- }
- if(newpt != pt)
- editor->setCurCanvasPart(newpt);
- }
- break;
- case CMD_MODIFY_GATE_TIME:
- {
- GateTime w(this);
- w.setRange(range);
- if (!w.exec())
- break;
- int range = w.range(); // all, selected, looped, sel+loop
- int rate = w.rateVal();
- int offset = w.offsetVal();
-
- song->startUndo();
- for (iCItem k = items.begin(); k != items.end(); ++k) {
- NEvent* nevent =(NEvent*)(k->second);
- Event event = nevent->event();
- if (event.type() != Note)
- continue;
- unsigned tick = event.tick();
- bool selected = k->second->isSelected();
- bool inLoop = (tick >= song->lpos()) && (tick < song->rpos());
-
- if ((range == 0)
- || (range == 1 && selected)
- || (range == 2 && inLoop)
- || (range == 3 && selected && inLoop)) {
- unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned
-
- len = rate ? (len * 100) / rate : 1;
- len += offset;
- if (len < 1)
- len = 1;
-
- if (event.lenTick() != len) {
- Event newEvent = event.clone();
- newEvent.setLenTick(len);
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, nevent->part(), false);
- audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false);
- }
- }
- }
- song->endUndo(SC_EVENT_MODIFIED);
- }
- break;
-
- case CMD_MODIFY_VELOCITY:
- {
- Velocity w;
- w.setRange(range);
- if (!w.exec())
- break;
- int range = w.range(); // all, selected, looped, sel+loop
- int rate = w.rateVal();
- int offset = w.offsetVal();
-
- song->startUndo();
- for (iCItem k = items.begin(); k != items.end(); ++k) {
- NEvent* nevent = (NEvent*)(k->second);
- Event event = nevent->event();
- if (event.type() != Note)
- continue;
- unsigned tick = event.tick();
- bool selected = k->second->isSelected();
- bool inLoop = (tick >= song->lpos()) && (tick < song->rpos());
-
- if ((range == 0)
- || (range == 1 && selected)
- || (range == 2 && inLoop)
- || (range == 3 && selected && inLoop)) {
- int velo = event.velo();
-
- //velo = rate ? (velo * 100) / rate : 64;
- velo = (velo * rate) / 100;
- velo += offset;
-
- if (velo <= 0)
- velo = 1;
- if (velo > 127)
- velo = 127;
- if (event.velo() != velo) {
- Event newEvent = event.clone();
- newEvent.setVelo(velo);
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, nevent->part(), false);
- audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false);
- }
- }
- }
- song->endUndo(SC_EVENT_MODIFIED);
- }
- break;
-
- case CMD_FIXED_LEN: //Set notes to the length specified in the drummap
- if (!selectionSize())
- break;
- song->startUndo();
- for (iCItem k = items.begin(); k != items.end(); ++k) {
- if (k->second->isSelected()) {
- NEvent* nevent = (NEvent*)(k->second);
- Event event = nevent->event();
- Event newEvent = event.clone();
- newEvent.setLenTick(editor->raster());
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, nevent->part() , false);
- audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false);
- }
- }
- song->endUndo(SC_EVENT_MODIFIED);
- break;
-
- case CMD_DELETE_OVERLAPS:
- if (!selectionSize())
- break;
-
- song->startUndo();
- for (iCItem k = items.begin(); k != items.end(); k++) {
- if (k->second->isSelected() == false)
- continue;
-
- NEvent* e1 = (NEvent*) (k->second); // first note
- NEvent* e2 = NULL; // ptr to next selected note (which will be checked for overlap)
- Event ce1 = e1->event();
- Event ce2;
-
- if (ce1.type() != Note)
- continue;
-
- // Find next selected item on the same pitch
- iCItem l = k; l++;
- for (; l != items.end(); l++) {
- if (l->second->isSelected() == false)
- continue;
-
- e2 = (NEvent*) l->second;
- ce2 = e2->event();
-
- // Same pitch?
- if (ce1.dataA() == ce2.dataA())
- break;
-
- // If the note has the same len and place we treat it as a duplicate note and not a following note
- // The best thing to do would probably be to delete the duplicate note, we just want to avoid
- // matching against the same note
- if ( ce1.tick() + e1->part()->tick() == ce2.tick() + e2->part()->tick()
- && ce1.lenTick() + e1->part()->tick() == ce2.lenTick() + e2->part()->tick())
- {
- e2 = NULL; // this wasn't what we were looking for
- continue;
- }
-
- }
-
- if (e2 == NULL) // None found
- break;
-
- Part* part1 = e1->part();
- Part* part2 = e2->part();
- if (ce2.type() != Note)
- continue;
-
-
- unsigned event1pos = ce1.tick() + part1->tick();
- unsigned event1end = event1pos + ce1.lenTick();
- unsigned event2pos = ce2.tick() + part2->tick();
-
- //printf("event1pos %u event1end %u event2pos %u\n", event1pos, event1end, event2pos);
- if (event1end > event2pos) {
- Event newEvent = ce1.clone();
- unsigned newlen = ce1.lenTick() - (event1end - event2pos);
- //printf("newlen: %u\n", newlen);
- newEvent.setLenTick(newlen);
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(ce1, newEvent, e1->part(), false);
- audio->msgChangeEvent(ce1, newEvent, e1->part(), false, false, false);
- }
- }
- song->endUndo(SC_EVENT_MODIFIED);
- break;
-
-
- case CMD_CRESCENDO:
- case CMD_TRANSPOSE:
- case CMD_THIN_OUT:
- case CMD_ERASE_EVENT:
- case CMD_NOTE_SHIFT:
- case CMD_MOVE_CLOCK:
- case CMD_COPY_MEASURE:
- case CMD_ERASE_MEASURE:
- case CMD_DELETE_MEASURE:
- case CMD_CREATE_MEASURE:
- break;
- default:
-// printf("unknown ecanvas cmd %d\n", cmd);
- break;
- }
- updateSelection();
- redraw();
- }
-
-//---------------------------------------------------------
-// quantize
-//---------------------------------------------------------
-
-void PianoCanvas::quantize(int strength, int limit, bool quantLen)
- {
- song->startUndo();
- for (iCItem k = items.begin(); k != items.end(); ++k) {
- NEvent* nevent = (NEvent*)(k->second);
- Event event = nevent->event();
- Part* part = nevent->part();
- if (event.type() != Note)
- continue;
-
- if ((cmdRange & CMD_RANGE_SELECTED) && !k->second->isSelected())
- continue;
-
- unsigned tick = event.tick() + part->tick();
-
- if ((cmdRange & CMD_RANGE_LOOP)
- && ((tick < song->lpos() || tick >= song->rpos())))
- continue;
-
- unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned
- int tick2 = tick + len;
-
- // quant start position
- int diff = AL::sigmap.raster(tick, editor->quant()) - tick;
- if (abs(diff) > limit)
- tick += ((diff * strength) / 100);
-
- // quant len
- diff = AL::sigmap.raster(tick2, editor->quant()) - tick2;
- if (quantLen && (abs(diff) > limit))
- len += ((diff * strength) / 100);
-
- // something changed?
- if (((event.tick() + part->tick()) != tick) || (event.lenTick() != len)) {
- Event newEvent = event.clone();
- newEvent.setTick(tick - part->tick());
- newEvent.setLenTick(len);
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, part, false);
- audio->msgChangeEvent(event, newEvent, part, false, false, false);
- }
- }
- song->endUndo(SC_EVENT_MODIFIED);
- }
-
-//---------------------------------------------------------
-// midiNote
-//---------------------------------------------------------
-
-void PianoCanvas::midiNote(int pitch, int velo)
- {
- if (_midiin && _steprec && curPart
- && !audio->isPlaying() && velo && pos[0] >= start_tick
- && pos[0] < end_tick
- && !(globalKeyState & Qt::AltModifier)) {
- unsigned int len = editor->quant();//prevent compiler warning: comparison singed/unsigned
- unsigned tick = pos[0]; //CDW
- unsigned starttick = tick;
- if (globalKeyState & Qt::ShiftModifier)
- tick -= editor->rasterStep(tick);
-
- //
- // extend len of last note?
- //
- EventList* events = curPart->events();
- if (globalKeyState & Qt::ControlModifier) {
- for (iEvent i = events->begin(); i != events->end(); ++i) {
- Event ev = i->second;
- if (!ev.isNote())
- continue;
- if (ev.pitch() == pitch && ((ev.tick() + ev.lenTick()) == /*(int)*/starttick)) {
- Event e = ev.clone();
- e.setLenTick(ev.lenTick() + editor->rasterStep(starttick));
- // Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(ev, e, curPart);
- audio->msgChangeEvent(ev, e, curPart, true, false, false);
- tick += editor->rasterStep(tick);
- if (tick != song->cpos()) {
- Pos p(tick, true);
- song->setPos(0, p, true, false, true);
- }
- return;
- }
- }
- }
-
- //
- // if we already entered the note, delete it
- //
- EventRange range = events->equal_range(tick);
- for (iEvent i = range.first; i != range.second; ++i) {
- Event ev = i->second;
- if (ev.isNote() && ev.pitch() == pitch) {
- // Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, curPart);
- audio->msgDeleteEvent(ev, curPart, true, false, false);
- if (globalKeyState & Qt::ShiftModifier)
- tick += editor->rasterStep(tick);
- return;
- }
- }
- Event e(Note);
- e.setTick(tick - curPart->tick());
- e.setPitch(pitch);
- e.setVelo(velo);
- e.setLenTick(len);
- // Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgAddEvent(e, curPart);
- audio->msgAddEvent(e, curPart, true, false, false);
- tick += editor->rasterStep(tick);
- if (tick != song->cpos()) {
- Pos p(tick, true);
- song->setPos(0, p, true, false, true);
- }
- }
- }
-
-/*
-//---------------------------------------------------------
-// getTextDrag
-//---------------------------------------------------------
-
-Q3TextDrag* PianoCanvas::getTextDrag(QWidget* parent)
- {
- //---------------------------------------------------
- // generate event list from selected events
- //---------------------------------------------------
-
- EventList el;
- unsigned startTick = MAXINT;
- for (iCItem i = items.begin(); i != items.end(); ++i) {
- if (!i->second->isSelected())
- continue;
- NEvent* ne = (NEvent*)(i->second);
- Event e = ne->event();
- if (startTick == MAXINT)
- startTick = e.tick();
- el.add(e);
- }
-
- //---------------------------------------------------
- // write events as XML into tmp file
- //---------------------------------------------------
-
- FILE* tmp = tmpfile();
- if (tmp == 0) {
- fprintf(stderr, "PianoCanvas::copy() fopen failed: %s\n",
- strerror(errno));
- return 0;
- }
- Xml xml(tmp);
-
- int level = 0;
- xml.tag(level++, "eventlist");
- for (ciEvent e = el.begin(); e != el.end(); ++e)
- e->second.write(level, xml, -startTick);
- xml.etag(--level, "eventlist");
-
- //---------------------------------------------------
- // read tmp file into QTextDrag Object
- //---------------------------------------------------
-
- fflush(tmp);
- struct stat f_stat;
- if (fstat(fileno(tmp), &f_stat) == -1) {
- fprintf(stderr, "PianoCanvas::copy() fstat failes:<%s>\n",
- strerror(errno));
- fclose(tmp);
- return 0;
- }
- int n = f_stat.st_size;
- char* fbuf = (char*)mmap(0, n+1, PROT_READ|PROT_WRITE,
- MAP_PRIVATE, fileno(tmp), 0);
- fbuf[n] = 0;
- Q3TextDrag* drag = new Q3TextDrag(QString(fbuf), parent);
- drag->setSubtype("eventlist");
- munmap(fbuf, n);
- fclose(tmp);
- return drag;
- }
-*/
-
-//---------------------------------------------------------
-// copy
-// cut copy paste
-//---------------------------------------------------------
-
-void PianoCanvas::copy()
- {
- //QDrag* drag = getTextDrag();
- QMimeData* drag = getTextDrag();
-
- if (drag)
- QApplication::clipboard()->setMimeData(drag, QClipboard::Clipboard);
- }
-
-/*
-//---------------------------------------------------------
-// pasteAt
-//---------------------------------------------------------
-
-void PianoCanvas::pasteAt(const QString& pt, int pos)
- {
- QByteArray ba = pt.toLatin1();
- const char* p = ba.constData();
- Xml xml(p);
- for (;;) {
- Xml::Token token = xml.parse();
- const QString& tag = xml.s1();
- switch (token) {
- case Xml::Error:
- case Xml::End:
- return;
- case Xml::TagStart:
- if (tag == "eventlist") {
- song->startUndo();
- EventList* el = new EventList();
- el->read(xml, "eventlist", true);
- int modified = SC_EVENT_INSERTED;
- for (iEvent i = el->begin(); i != el->end(); ++i) {
- Event e = i->second;
- int tick = e.tick() + pos - curPart->tick();
- if (tick<0) {
- printf("ERROR: trying to add event before current part!\n");
- song->endUndo(SC_EVENT_INSERTED);
- delete el;
- return;
- }
-
- e.setTick(tick);
- int diff = e.endTick()-curPart->lenTick();
- if (diff > 0) {// too short part? extend it
- Part* newPart = curPart->clone();
- newPart->setLenTick(newPart->lenTick()+diff);
- // Indicate no undo, and do port controller values but not clone parts.
- audio->msgChangePart(curPart, newPart, false, true, false);
- modified=modified|SC_PART_MODIFIED;
- curPart = newPart; // reassign
- }
- // Indicate no undo, and do not do port controller values and clone parts.
- audio->msgAddEvent(e, curPart, false, false, false);
- }
- song->endUndo(modified);
- delete el;
- return;
- }
- else
- xml.unknown("pasteAt");
- break;
- case Xml::Attribut:
- case Xml::TagEnd:
- default:
- break;
- }
- }
- }
-*/
-
-//---------------------------------------------------------
-// paste
-// paste events
-//---------------------------------------------------------
-
-void PianoCanvas::paste()
- {
-/*
- //Q3CString subtype("eventlist"); ddskrjo
- QString subtype("eventlist");
- QMimeSource* ms = QApplication::clipboard()->data(QClipboard::Clipboard);
- QString pt;
- if (!Q3TextDrag::decode(ms, pt, subtype)) {
- printf("cannot paste: bad data type\n");
- return;
- }
- pasteAt(pt, song->cpos());
-*/
- QString stype("x-muse-eventlist");
-
- //QString s = QApplication::clipboard()->text(stype, QClipboard::Selection);
- QString s = QApplication::clipboard()->text(stype, QClipboard::Clipboard); // TODO CHECK Tim.
-
- pasteAt(s, song->cpos());
- }
-
-//---------------------------------------------------------
-// startDrag
-//---------------------------------------------------------
-
-void PianoCanvas::startDrag(CItem* /* item*/, bool copymode)
- {
- QMimeData* md = getTextDrag();
- //QDrag* drag = getTextDrag();
-
- if (md) {
-// QApplication::clipboard()->setData(drag, QClipboard::Clipboard); // This line NOT enabled in muse-1
- //QApplication::clipboard()->setMimeData(md); // TODO CHECK Tim.
- //QApplication::clipboard()->setMimeData(drag->mimeData()); //
-
- // "Note that setMimeData() assigns ownership of the QMimeData object to the QDrag object.
- // The QDrag must be constructed on the heap with a parent QWidget to ensure that Qt can
- // clean up after the drag and drop operation has been completed. "
- QDrag* drag = new QDrag(this);
- drag->setMimeData(md);
-
- if (copymode)
- drag->exec(Qt::CopyAction);
- else
- drag->exec(Qt::MoveAction);
- }
- }
-
-//---------------------------------------------------------
-// dragEnterEvent
-//---------------------------------------------------------
-
-void PianoCanvas::dragEnterEvent(QDragEnterEvent* event)
- {
- ///event->accept(Q3TextDrag::canDecode(event));
- event->acceptProposedAction(); // TODO CHECK Tim.
- }
-
-//---------------------------------------------------------
-// dragMoveEvent
-//---------------------------------------------------------
-
-void PianoCanvas::dragMoveEvent(QDragMoveEvent*)
- {
- //printf("drag move %x\n", this);
- //event->acceptProposedAction();
- }
-
-//---------------------------------------------------------
-// dragLeaveEvent
-//---------------------------------------------------------
-
-void PianoCanvas::dragLeaveEvent(QDragLeaveEvent*)
- {
- //printf("drag leave\n");
- //event->acceptProposedAction();
- }
-
-/*
-//---------------------------------------------------------
-// dropEvent
-//---------------------------------------------------------
-
-void PianoCanvas::viewDropEvent(QDropEvent* event)
- {
- QString text;
- if (event->source() == this) {
- printf("local DROP\n"); // REMOVE Tim
- //event->acceptProposedAction();
- //event->ignore(); // TODO CHECK Tim.
- return;
- }
- ///if (Q3TextDrag::decode(event, text)) {
- //if (event->mimeData()->hasText()) {
- if (event->mimeData()->hasFormat("text/x-muse-eventlist")) {
-
- //text = event->mimeData()->text();
- text = QString(event->mimeData()->data("text/x-muse-eventlist"));
-
- int x = editor->rasterVal(event->pos().x());
- if (x < 0)
- x = 0;
- pasteAt(text, x);
- //event->accept(); // TODO
- }
- else {
- printf("cannot decode drop\n");
- //event->acceptProposedAction();
- //event->ignore(); // TODO CHECK Tim.
- }
- }
-*/
-
-//---------------------------------------------------------
-// itemPressed
-//---------------------------------------------------------
-
-void PianoCanvas::itemPressed(const CItem* item)
- {
- if (!_playEvents)
- return;
-
- int port = track()->outPort();
- int channel = track()->outChannel();
- NEvent* nevent = (NEvent*) item;
- Event event = nevent->event();
- playedPitch = event.pitch() + track()->transposition;
- int velo = event.velo();
-
- // play note:
- MidiPlayEvent e(0, port, channel, 0x90, playedPitch, velo);
- audio->msgPlayMidiEvent(&e);
- }
-
-//---------------------------------------------------------
-// itemReleased
-//---------------------------------------------------------
-
-void PianoCanvas::itemReleased(const CItem*, const QPoint&)
- {
- if (!_playEvents)
- return;
- int port = track()->outPort();
- int channel = track()->outChannel();
-
- // release note:
- MidiPlayEvent ev(0, port, channel, 0x90, playedPitch, 0);
- audio->msgPlayMidiEvent(&ev);
- playedPitch = -1;
- }
-
-//---------------------------------------------------------
-// itemMoved
-//---------------------------------------------------------
-
-void PianoCanvas::itemMoved(const CItem* item, const QPoint& pos)
- {
- int npitch = y2pitch(pos.y());
- if ((playedPitch != -1) && (playedPitch != npitch)) {
- int port = track()->outPort();
- int channel = track()->outChannel();
- NEvent* nevent = (NEvent*) item;
- Event event = nevent->event();
-
- // release note:
- MidiPlayEvent ev1(0, port, channel, 0x90, playedPitch, 0);
- audio->msgPlayMidiEvent(&ev1);
- // play note:
- MidiPlayEvent e2(0, port, channel, 0x90, npitch + track()->transposition, event.velo());
- audio->msgPlayMidiEvent(&e2);
- playedPitch = npitch + track()->transposition;
- }
- }
-
-//---------------------------------------------------------
-// curPartChanged
-//---------------------------------------------------------
-
-void PianoCanvas::curPartChanged()
- {
- editor->setWindowTitle(getCaption());
- }
-
-//---------------------------------------------------------
-// modifySelected
-//---------------------------------------------------------
-
-void PianoCanvas::modifySelected(NoteInfo::ValType type, int delta)
- {
- audio->msgIdle(true);
- song->startUndo();
- for (iCItem i = items.begin(); i != items.end(); ++i) {
- if (!(i->second->isSelected()))
- continue;
- NEvent* e = (NEvent*)(i->second);
- Event event = e->event();
- if (event.type() != Note)
- continue;
-
- MidiPart* part = (MidiPart*)(e->part());
- Event newEvent = event.clone();
-
- switch (type) {
- case NoteInfo::VAL_TIME:
- {
- int newTime = event.tick() + delta;
- if (newTime < 0)
- newTime = 0;
- newEvent.setTick(newTime);
- }
- break;
- case NoteInfo::VAL_LEN:
- {
- int len = event.lenTick() + delta;
- if (len < 1)
- len = 1;
- newEvent.setLenTick(len);
- }
- break;
- case NoteInfo::VAL_VELON:
- {
- int velo = event.velo() + delta;
- if (velo > 127)
- velo = 127;
- else if (velo < 0)
- velo = 0;
- newEvent.setVelo(velo);
- }
- break;
- case NoteInfo::VAL_VELOFF:
- {
- int velo = event.veloOff() + delta;
- if (velo > 127)
- velo = 127;
- else if (velo < 0)
- velo = 0;
- newEvent.setVeloOff(velo);
- }
- break;
- case NoteInfo::VAL_PITCH:
- {
- int pitch = event.pitch() + delta;
- if (pitch > 127)
- pitch = 127;
- else if (pitch < 0)
- pitch = 0;
- newEvent.setPitch(pitch);
- }
- break;
- }
- song->changeEvent(event, newEvent, part);
- // Indicate do not do port controller values and clone parts.
- //song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
- song->undoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false);
- }
- song->endUndo(SC_EVENT_MODIFIED);
- audio->msgIdle(false);
- }
-
-//---------------------------------------------------------
-// resizeEvent
-//---------------------------------------------------------
-
-void PianoCanvas::resizeEvent(QResizeEvent* ev)
- {
- if (ev->size().width() != ev->oldSize().width())
- emit newWidth(ev->size().width());
- EventCanvas::resizeEvent(ev);
- }
-