summaryrefslogtreecommitdiff
path: root/attic/muse2-oom/muse2/muse/midiedit/dcanvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse2-oom/muse2/muse/midiedit/dcanvas.cpp')
-rw-r--r--attic/muse2-oom/muse2/muse/midiedit/dcanvas.cpp1351
1 files changed, 0 insertions, 1351 deletions
diff --git a/attic/muse2-oom/muse2/muse/midiedit/dcanvas.cpp b/attic/muse2-oom/muse2/muse/midiedit/dcanvas.cpp
deleted file mode 100644
index 34622296..00000000
--- a/attic/muse2-oom/muse2/muse/midiedit/dcanvas.cpp
+++ /dev/null
@@ -1,1351 +0,0 @@
-//=========================================================
-// MusE
-// Linux Music Editor
-// $Id: dcanvas.cpp,v 1.16.2.10 2009/10/15 22:45:50 terminator356 Exp $
-// (C) Copyright 1999 Werner Schweer (ws@seh.de)
-//=========================================================
-
-#include <QPainter>
-#include <QApplication>
-#include <QClipboard>
-#include <QDrag>
-#include <QDragLeaveEvent>
-#include <QPolygon>
-#include <QDragEnterEvent>
-#include <QDragMoveEvent>
-#include <QDropEvent>
-#include <QResizeEvent>
-
-#include <stdio.h>
-#include <values.h>
-#include <errno.h>
-//#include <sys/stat.h>
-//#include <sys/mman.h>
-
-#include "dcanvas.h"
-#include "midieditor.h"
-#include "drummap.h"
-#include "event.h"
-#include "mpevent.h"
-#include "xml.h"
-#include "globals.h"
-#include "midiport.h"
-#include "audio.h"
-#include "velocity.h"
-
-#define CARET 10
-#define CARET2 5
-
-//---------------------------------------------------------
-// DEvent
-//---------------------------------------------------------
-
-DEvent::DEvent(Event e, Part* p)
- : CItem(e, p)
- {
- int instr = e.pitch();
- int y = instr * TH + TH/2;
- int tick = e.tick() + p->tick();
- setPos(QPoint(tick, y));
- setBBox(QRect(-CARET2, -CARET2, CARET, CARET));
- }
-
-//---------------------------------------------------------
-// addItem
-//---------------------------------------------------------
-
-void DrumCanvas::addItem(Part* part, Event& event)
- {
- if (signed(event.tick())<0) {
- printf("ERROR: trying to add event before current part!\n");
- return;
- }
-
- DEvent* ev = new DEvent(event, part);
- 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);
- }
- }
-
-//---------------------------------------------------------
-// DrumCanvas
-//---------------------------------------------------------
-
-DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx,
- int sy, const char* name)
- : EventCanvas(pr, parent, sx, sy, name)
- {
- setVirt(false);
- songChanged(SC_TRACK_INSERTED);
- }
-
-//---------------------------------------------------------
-// moveCanvasItems
-//---------------------------------------------------------
-
-void DrumCanvas::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...
- DEvent* nevent = (DEvent*) 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);
- 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
-//---------------------------------------------------------
-
-// Changed by T356.
-//bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype, int* pflags)
-bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)
- {
- DEvent* nevent = (DEvent*) item;
-
- // Changed by T356.
- //MidiPart* part = (MidiPart*)Canvas::part(); // part can be dynamically recreated, ask the authority
- MidiPart* part = (MidiPart*)nevent->part();
-
- Event event = nevent->event();
- int x = pos.x();
- if (x < 0)
- x = 0;
- int ntick = editor->rasterVal(x) - part->tick();
- if (ntick < 0)
- ntick = 0;
- int npitch = y2pitch(pos.y());
- Event newEvent = event.clone();
-
- newEvent.setPitch(npitch);
- newEvent.setTick(ntick);
-
- // Removed by T356.
- /*
- // Added 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();
- MidiPart* newPart = (MidiPart*)Canvas::part()->clone();
- newPart->setLenTick(newPart->lenTick()+diff);
- audio->msgChangePart(Canvas::part(), newPart,false);
-
- modified = SC_PART_MODIFIED;
- part = newPart; // reassign
- 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("DrumCanvas::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);
- }
-
- // Removed by T356.
- //if(pflags)
- // *pflags = modified;
-
- return true;
- }
-
-//---------------------------------------------------------
-// newItem
-//---------------------------------------------------------
-
-CItem* DrumCanvas::newItem(const QPoint& p, int state)
- {
- int instr = y2pitch(p.y()); //drumInmap[y2pitch(p.y())];
- int velo = drumMap[instr].lv4;
- if (state == Qt::ShiftModifier)
- velo = drumMap[instr].lv3;
- else if (state == Qt::ControlModifier)
- velo = drumMap[instr].lv2;
- else if (state == (Qt::ControlModifier | Qt::ShiftModifier))
- velo = drumMap[instr].lv1;
- int tick = editor->rasterVal(p.x());
- tick -= curPart->tick();
- Event e(Note);
- e.setTick(tick);
- e.setPitch(instr);
- e.setVelo(velo);
- e.setLenTick(drumMap[instr].len);
- return new DEvent(e, curPart);
- }
-
-//---------------------------------------------------------
-// resizeItem
-//---------------------------------------------------------
-
-void DrumCanvas::resizeItem(CItem* item, bool)
- {
- DEvent* nevent = (DEvent*) item;
- Event ev = nevent->event();
- // Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, nevent->part());
- audio->msgDeleteEvent(ev, nevent->part(), true, false, false);
- }
-
-//---------------------------------------------------------
-// newItem
-//---------------------------------------------------------
-
-void DrumCanvas::newItem(CItem* item, bool noSnap)
- {
- DEvent* nevent = (DEvent*) item;
- Event event = nevent->event();
- int x = item->x();
- if (!noSnap)
- x = editor->rasterVal(x);
- event.setTick(x - nevent->part()->tick());
- //int npitch = drumMap[y2pitch(item->y())].enote;
- int npitch = event.pitch();
- event.setPitch(npitch);
-
- //
- // check for existing event
- // if found change command semantic from insert to delete
- //
- EventList* el = nevent->part()->events();
- iEvent lower = el->lower_bound(event.tick());
- iEvent upper = el->upper_bound(event.tick());
-
- for (iEvent i = lower; i != upper; ++i) {
- Event ev = i->second;
- // Added by T356. Only do notes.
- if(!ev.isNote())
- continue;
-
- if (ev.pitch() == npitch) {
- // Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, nevent->part());
- audio->msgDeleteEvent(ev, nevent->part(), true, false, false);
- return;
- }
- }
-
- // Added by T356.
- Part* part = nevent->part();
- 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);
-
- //audio->msgAddEvent(event, nevent->part());
- }
-
-//---------------------------------------------------------
-// deleteItem
-//---------------------------------------------------------
-
-bool DrumCanvas::deleteItem(CItem* item)
- {
- Event ev = ((DEvent*)item)->event();
- // Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, ((DEvent*)item)->part());
- audio->msgDeleteEvent(ev, ((DEvent*)item)->part(), true, false, false);
- return false;
- }
-
-//---------------------------------------------------------
-// drawItem
-//---------------------------------------------------------
-
-void DrumCanvas::drawItem(QPainter&p, const CItem*item, const QRect& rect)
- {
- DEvent* e = (DEvent*) item;
- int x = 0, y = 0;
- x = mapx(item->pos().x());
- y = mapy(item->pos().y());
- QPolygon pa(4);
- pa.setPoint(0, x - CARET2, y);
- pa.setPoint(1, x, y - CARET2);
- pa.setPoint(2, x + CARET2, y);
- pa.setPoint(3, x, y + CARET2);
- QRect r(pa.boundingRect());
- r = r.intersect(rect);
- if(!r.isValid())
- return;
-
- p.setPen(Qt::black);
-
- if (e->part() != curPart)
- {
- if(item->isMoving())
- p.setBrush(Qt::gray);
- else if(item->isSelected())
- p.setBrush(Qt::black);
- else
- p.setBrush(Qt::lightGray);
- }
- else if (item->isMoving()) {
- p.setBrush(Qt::gray);
- }
- else if (item->isSelected())
- {
- p.setBrush(Qt::black);
- }
- else
- {
- int velo = e->event().velo();
- DrumMap* dm = &drumMap[y2pitch(y)]; //Get the drum item
- QColor color;
- if (velo < dm->lv1)
- color.setRgb(240, 240, 255);
- else if (velo < dm->lv2)
- color.setRgb(200, 200, 255);
- else if (velo < dm->lv3)
- color.setRgb(170, 170, 255);
- else
- color.setRgb(0, 0, 255);
- p.setBrush(color);
- }
-
- p.drawPolygon(pa);
- }
-
-//---------------------------------------------------------
-// drawMoving
-// draws moving items
-//---------------------------------------------------------
-
-void DrumCanvas::drawMoving(QPainter& p, const CItem* item, const QRect& rect)
- {
- //if(((DEvent*)item)->part() != curPart)
- // return;
- //if(!item->isMoving())
- // return;
- QPolygon pa(4);
- QPoint pt = map(item->mp());
- int x = pt.x();
- int y = pt.y();
- pa.setPoint(0, x-CARET2, y + TH/2);
- pa.setPoint(1, x, y + TH/2+CARET2);
- pa.setPoint(2, x+CARET2, y + TH/2);
- pa.setPoint(3, x, y + (TH-CARET)/2);
- QRect mr(pa.boundingRect());
- mr = mr.intersect(rect);
- if(!mr.isValid())
- return;
- p.setPen(Qt::black);
- p.setBrush(Qt::black);
- p.drawPolygon(pa);
- }
-
-//---------------------------------------------------------
-// drawCanvas
-//---------------------------------------------------------
-
-extern void drawTickRaster(QPainter& p, int, int, int, int, int);
-
-void DrumCanvas::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) / TH) * TH + TH;
- for (; yy < y + h; yy += TH) {
- p.setPen(Qt::gray);
- p.drawLine(x, yy, x + w, yy);
- }
-
- //---------------------------------------------------
- // vertical lines
- //---------------------------------------------------
-
- drawTickRaster(p, x, y, w, h, editor->raster());
- }
-
-//---------------------------------------------------------
-// y2pitch
-//---------------------------------------------------------
-
-int DrumCanvas::y2pitch(int y) const
- {
- int pitch = y/TH;
- if (pitch >= DRUM_MAPSIZE)
- pitch = DRUM_MAPSIZE-1;
- return pitch;
- }
-
-//---------------------------------------------------------
-// pitch2y
-//---------------------------------------------------------
-
-int DrumCanvas::pitch2y(int pitch) const
- {
- return pitch * TH;
- }
-
-//---------------------------------------------------------
-// cmd
-//---------------------------------------------------------
-
-void DrumCanvas::cmd(int cmd)
- {
- switch(cmd) {
- case CMD_CUT:
- copy();
- song->startUndo();
- for (iCItem i = items.begin(); i != items.end(); ++i) {
- if (!i->second->isSelected())
- continue;
- DEvent* e = (DEvent*)(i->second);
- Event event = e->event();
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(event, e->part(), false);
- audio->msgDeleteEvent(event, e->part(), false, false, false);
- }
- song->endUndo(SC_EVENT_REMOVED);
- break;
- case CMD_COPY:
- copy();
- break;
- case CMD_PASTE:
- paste();
- 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) {
- DEvent* nevent =(DEvent*)(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) {
- DEvent* nevent = (DEvent*)(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_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_SAVE:
- case CMD_LOAD:
- printf("DrumCanvas:: cmd not implemented %d\n", cmd);
- 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()) {
- DEvent* devent = (DEvent*)(k->second);
- Event event = devent->event();
- Event newEvent = event.clone();
- newEvent.setLenTick(drumMap[event.pitch()].len);
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, devent->part() , false);
- audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false);
- }
- }
- song->endUndo(SC_EVENT_MODIFIED);
- break;
- 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_MODIFY_VELOCITY:
- {
- Velocity w;
- w.setRange(0); //TODO: Make this work! Probably put _to & _toInit in ecanvas instead
- 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) {
- DEvent* devent = (DEvent*)(k->second);
- Event event = devent->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, devent->part(), false);
- audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false);
- }
- }
- }
- song->endUndo(SC_EVENT_MODIFIED);
- }
- break;
- }
- updateSelection();
- redraw();
- }
-
-/*
-//---------------------------------------------------------
-// getTextDrag
-//---------------------------------------------------------
-
-Q3TextDrag* DrumCanvas::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;
- DEvent* ne = (DEvent*)(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, "EventCanvas::copy() fopen failed: %s\n",
- strerror(errno));
- return 0;
- }
- Xml xml(tmp);
-
- int level = 0;
- for (ciEvent e = el.begin(); e != el.end(); ++e)
- e->second.write(level, xml, -startTick);
-
- //---------------------------------------------------
- // read tmp file into QTextDrag Object
- //---------------------------------------------------
-
- fflush(tmp);
- struct stat f_stat;
- if (fstat(fileno(tmp), &f_stat) == -1) {
- fprintf(stderr, "EventCanvas::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 DrumCanvas::copy()
- {
- //QDrag* drag = getTextDrag();
- QMimeData* md = getTextDrag();
-
- if (md)
- QApplication::clipboard()->setMimeData(md, QClipboard::Clipboard);
- }
-
-/*
-//---------------------------------------------------------
-// paste
-//---------------------------------------------------------
-
-int DrumCanvas::pasteAt(const QString& pt, int pos)
- {
- QByteArray ba = pt.toLatin1();
- const char* p = ba.constData();
- Xml xml(p);
-
- // Added by T356.
- int modified = SC_EVENT_INSERTED;
-
- song->startUndo();
- for (;;) {
- Xml::Token token = xml.parse();
- QString tag = xml.s1();
- switch (token) {
- case Xml::Error:
- case Xml::End:
- song->endUndo(modified);
- return pos;
- case Xml::TagStart:
- if (tag == "event") {
- Event e(Note);
- e.read(xml);
-
- // Added by T356.
- int tick = e.tick() + pos - curPart->tick();
- if (tick<0) {
- printf("DrumCanvas::pasteAt ERROR: trying to add event before current part!\n");
- song->endUndo(SC_EVENT_INSERTED);
- //delete el;
- return pos;
- }
- 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);
- }
- else
- xml.unknown("DCanvas::pasteAt");
- break;
- case Xml::TagEnd:
- default:
- break;
- }
- }
- }
-*/
-
-//---------------------------------------------------------
-// paste
-// paste events
-//---------------------------------------------------------
-
-void DrumCanvas::paste()
- {
-/*
-// Q3CString subtype("eventlist"); // ddskrjo
- QString subtype("eventlist");
- QMimeSource* ms = QApplication::clipboard()->data();
- 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 DrumCanvas::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 DrumCanvas::dragEnterEvent(QDragEnterEvent* event)
- {
- ///event->accept(Q3TextDrag::canDecode(event));
- event->acceptProposedAction(); // TODO CHECK Tim.
- }
-
-//---------------------------------------------------------
-// dragMoveEvent
-//---------------------------------------------------------
-
-void DrumCanvas::dragMoveEvent(QDragMoveEvent*)
- {
- //printf("drag move %x\n", this); // REMOVE Tim
- //event->acceptProposedAction();
- }
-
-//---------------------------------------------------------
-// dragLeaveEvent
-//---------------------------------------------------------
-
-void DrumCanvas::dragLeaveEvent(QDragLeaveEvent*)
- {
- //printf("drag leave\n"); // REMOVE Tim
- //event->acceptProposedAction();
- }
-
-/*
-//---------------------------------------------------------
-// dropEvent
-//---------------------------------------------------------
-
-void DrumCanvas::viewDropEvent(QDropEvent* event)
- {
- QString text;
- if (event->source() == this) {
- printf("local DROP\n"); // REMOVE Tim
- //event->acceptProposedAction();
- //event->ignore(); // TODO CHECK Tim.
- return;
- }
- //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"));
-
-// printf("drop <%s>\n", text.ascii());
- 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.
- }
- }
-*/
-
-//---------------------------------------------------------
-// keyPressed
-//---------------------------------------------------------
-
-void DrumCanvas::keyPressed(int index, bool)
- {
- int port = drumMap[index].port;
- int channel = drumMap[index].channel;
- int pitch = drumMap[index].anote;
-
- // play note:
- MidiPlayEvent e(0, port, channel, 0x90, pitch, 127);
- audio->msgPlayMidiEvent(&e);
- }
-
-//---------------------------------------------------------
-// keyReleased
-//---------------------------------------------------------
-
-void DrumCanvas::keyReleased(int index, bool)
- {
- int port = drumMap[index].port;
- int channel = drumMap[index].channel;
- int pitch = drumMap[index].anote;
-
- // release note:
- MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
- audio->msgPlayMidiEvent(&e);
- }
-
-//---------------------------------------------------------
-// mapChanged
-//---------------------------------------------------------
-
-void DrumCanvas::mapChanged(int spitch, int dpitch)
- {
- //TODO: Circumvent undo behaviour, since this isn't really a true change of the events,
- // but merely a change in pitch because the pitch relates to the order of the dlist.
- // Right now the sequencer spits out internalError: undoOp without startUndo() if start/stopundo is there, which is misleading
- // If start/stopundo is there, undo misbehaves since it doesn't undo but messes things up
- // Other solution: implement a specific undo-event for this (SC_DRUMMAP_MODIFIED or something) which undoes movement of
- // dlist-items (ml)
-
- std::vector< std::pair<Part*, Event*> > delete_events;
- std::vector< std::pair<Part*, Event> > add_events;
-
- typedef std::vector< std::pair<Part*, Event*> >::iterator idel_ev;
- typedef std::vector< std::pair<Part*, Event> >::iterator iadd_ev;
-
- /*
- class delete_events : public std::vector< Part*, Event* >
- {
- public:
- idel_ev find(Part* p, Event* e)
- {
-
- };
- };
- class add_events : public std::vector< Part*, Event >
- {
- public:
- iadd_ev find(Part* p, Event& e)
- {
-
- };
- };
- */
-
- MidiTrackList* tracks = song->midis();
- for (ciMidiTrack t = tracks->begin(); t != tracks->end(); t++) {
- MidiTrack* curTrack = *t;
- if (curTrack->type() != Track::DRUM)
- continue;
-
- MidiPort* mp = &midiPorts[curTrack->outPort()];
- PartList* parts= curTrack->parts();
- for (iPart part = parts->begin(); part != parts->end(); ++part) {
- EventList* events = part->second->events();
- Part* thePart = part->second;
- for (iEvent i = events->begin(); i != events->end(); ++i) {
- Event event = i->second;
- if(event.type() != Controller && event.type() != Note)
- continue;
- int pitch = event.pitch();
- bool drc = false;
- // Is it a drum controller event, according to the track port's instrument?
- if(event.type() == Controller && mp->drumController(event.dataA()))
- {
- drc = true;
- pitch = event.dataA() & 0x7f;
- }
-
- if (pitch == spitch) {
- Event* spitch_event = &(i->second);
- delete_events.push_back(std::pair<Part*, Event*>(thePart, spitch_event));
- Event newEvent = spitch_event->clone();
- if(drc)
- newEvent.setA((newEvent.dataA() & ~0xff) | dpitch);
- else
- newEvent.setPitch(dpitch);
- add_events.push_back(std::pair<Part*, Event>(thePart, newEvent));
- }
- else if (pitch == dpitch) {
- Event* dpitch_event = &(i->second);
- delete_events.push_back(std::pair<Part*, Event*>(thePart, dpitch_event));
- Event newEvent = dpitch_event->clone();
- if(drc)
- newEvent.setA((newEvent.dataA() & ~0xff) | spitch);
- else
- newEvent.setPitch(spitch);
- add_events.push_back(std::pair<Part*, Event>(thePart, newEvent));
- }
- }
- }
- }
-
- song->startUndo();
- for (idel_ev i = delete_events.begin(); i != delete_events.end(); i++) {
- //std::pair<Part*, Event*> pair = *i;
- //Part* thePart = pair.first;
- //Event* theEvent = pair.second;
- Part* thePart = (*i).first;
- Event* theEvent = (*i).second;
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgDeleteEvent(*theEvent, thePart, false);
- audio->msgDeleteEvent(*theEvent, thePart, false, true, false);
- }
-
- DrumMap dm = drumMap[spitch];
- drumMap[spitch] = drumMap[dpitch];
- drumMap[dpitch] = dm;
- drumInmap[int(drumMap[spitch].enote)] = spitch;
- drumOutmap[int(drumMap[int(spitch)].anote)] = spitch;
- drumInmap[int(drumMap[int(dpitch)].enote)] = dpitch;
- drumOutmap[int(drumMap[int(dpitch)].anote)] = dpitch;
-
- for (iadd_ev i = add_events.begin(); i != add_events.end(); i++) {
- //std::pair<Part*, Event> pair = *i;
- //Part* thePart = pair.first;
- //Event& theEvent = pair.second;
- Part* thePart = (*i).first;
- Event& theEvent = (*i).second;
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgAddEvent(theEvent, thePart, false);
- audio->msgAddEvent(theEvent, thePart, false, true, false);
- }
-
- song->endUndo(SC_EVENT_MODIFIED);
- song->update(SC_DRUMMAP);
- }
-
-//---------------------------------------------------------
-// resizeEvent
-//---------------------------------------------------------
-
-void DrumCanvas::resizeEvent(QResizeEvent* ev)
- {
- if (ev->size().width() != ev->oldSize().width())
- emit newWidth(ev->size().width());
- EventCanvas::resizeEvent(ev);
- }
-
-
-//---------------------------------------------------------
-// modifySelected
-//---------------------------------------------------------
-
-void DrumCanvas::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;
- DEvent* e = (DEvent*)(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);
- }
- */
- printf("DrumCanvas::modifySelected - NoteInfo::VAL_LEN not implemented\n");
- break;
- case NoteInfo::VAL_VELON:
- /*
- {
- int velo = event->velo() + delta;
- if (velo > 127)
- velo = 127;
- else if (velo < 0)
- velo = 0;
- newEvent.setVelo(velo);
- }
- */
- printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELON not implemented\n");
- break;
- case NoteInfo::VAL_VELOFF:
- /*
- {
- int velo = event.veloOff() + delta;
- if (velo > 127)
- velo = 127;
- else if (velo < 0)
- velo = 0;
- newEvent.setVeloOff(velo);
- }
- */
- printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELOFF not implemented\n");
- break;
- case NoteInfo::VAL_PITCH:
- {
- int pitch = event.pitch() - delta; // Reversing order since the drumlist is displayed in increasing order
- 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);
- }
-
-//---------------------------------------------------------
-// curPartChanged
-//---------------------------------------------------------
-
-void DrumCanvas::curPartChanged()
- {
- editor->setWindowTitle(getCaption());
- }
-